Прежде всего, если вы посмотрите на рассол документов , в частности:
pickle может прозрачно сохранять и восстанавливать экземпляры классов, однако определение класса должно быть импортируемым и находиться в том же модуле, что и при сохранении объекта
Итак, это говорит нам о том, что pickle импортирует модуль, который определяет объект, который вы очищаете.
Мы можем показать это на небольшом примере, рассмотрим следующую структуру папок:
parent/
|-- a.py
|-- sub/
sub
- это пустая подпапка
a.py
содержит пример класса
# a.py
class ExampleClass:
def __init__(self):
self.var = 'This is a string'
Теперь запускаем консоль python
в каталоге parent
:
alex@toaster:parent$ python3
>>> import pickle
>>> from a import ExampleClass
>>> x = ExampleClass()
>>> x.var
'This is a string'
>>> with open('eg.p', 'wb') as f:
... pickle.dump(x, f)
Выход из оболочки. Перейдите в каталог sub
и попробуйте загрузить маринованный объект ExampleClass
.
alex@toaster:sub$ python3
>>> import pickle
>>> with open('../eg.p', 'rb') as f:
... x = pickle.load(f)
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ModuleNotFoundError: No module named 'a'
Мы получаем ModuleNotFoundError
, так как pickle не может загрузить определение класса из модуля a
(он находится в другом каталоге). В вашем случае python может загрузить класс collections.defaultdict
, так как этот модуль находится на PYTHONPATH
. Однако, чтобы продолжить использовать модули, импортированные с помощью pickle, вам все равно придется импортировать их самостоятельно; например, вы хотите создать еще один defaultdict
в script2.py
.
Чтобы узнать больше о модулях, посмотрите здесь , в частности 6.1.2 Путь поиска модуля .