我正在学习如何使用泡菜。我创建了一个 namedtuple 对象,将其附加到列表中,并尝试对该列表进行 pickle。但是,我收到以下错误:
pickle.PicklingError: Can't pickle <class '__main__.P'>: it's not found as __main__.P
我发现如果我运行代码而不将其包装在函数中,它会完美运行。当包裹在函数中时,是否需要额外的步骤来腌制对象?
这是我的代码:
from collections import namedtuple
import pickle
def pickle_test():
P = namedtuple("P", "one two three four")
my_list = []
abe = P("abraham", "lincoln", "vampire", "hunter")
my_list.append(abe)
with open('abe.pickle', 'wb') as f:
pickle.dump(abe, f)
pickle_test()
原文由 Dirty Penguin 发布,翻译遵循 CC BY-SA 4.0 许可协议
在函数 外部 创建命名元组:
现在
pickle
可以找到了;它现在是一个全球模块。 unpickling 时,所有pickle
模块所要做的就是再次定位__main__.P
。在您的版本中,P
是pickle_test()
函数的 _本地_,并且不可自省或不可导入。请注意,
pickle
仅存储模块和类名,取自类的__name__
属性。确保namedtuple()
调用的第一个参数与您分配给的全局变量相匹配;P.__name__
必须是"P"
!重要的是要记住
namedtuple()
是一个类工厂;你给它参数,它返回一个类对象供你创建实例。pickle
仅存储实例中包含的 _数据_,加上对原始类的字符串引用以再次重构实例。