Можно упаковывать следующие типы:
None
, True
и False
;def
, lambda-функции упаковывать нельзя;Попытки упаковать необратимые объекты вызовут исключение PicklingError
. Когда это происходит, то в базовый файл уже может быть записано неопределенное количество байтов. Попытка выбрать многорекурсивную структуру данных может превысить максимальную глубину рекурсии, в этом случае будет вызвана ошибка RecursionError
. Вы можете осторожно поднять этот предел с помощью sys.setrecursionlimit()
.
Обратите внимание, что функции (встроенные и определяемые пользователем) выбираются по "полной" ссылке на имя, а не по значению. Это означает, что выбирается только имя функции, а также имя модуля, в котором определена функция. Ни код функции, ни какой-либо из ее атрибутов функции не выбираются. Таким образом определяющий модуль должен быть импортируемым в среде распаковки и модуль должен содержать именованный объект, в противном случае будет сгенерировано исключение.
Точно так же классы выбираются по именованным ссылкам, поэтому применяются те же ограничения в среде удаления. Обратите внимание, что ни код, ни данные класса не упакованы, поэтому в следующем примере атрибута attr
класса не восстанавливается в среде распаковки:
class Foo: attr = 'A class attribute' picklestring = pickle.dumps(Foo)
Именно из-за этих ограничений выбираемые функции и классы должны быть определены на верхнем уровне модуля.
Точно так же, когда экземпляры класса подвергаются сериализации, код и данные их класса не обрабатываются вместе с ними. Только данные экземпляра упаковываются. Это сделано специально, поэтому можно исправлять ошибки в классе или добавлять методы к классу и по-прежнему загружать объекты, созданные в более ранней версии класса.