我正在学习如何使用 pickle 。我创建了一个 namedtuple 对象,将它附加到一个列表中,并试图对这个列表进行 pickle 。但是,我收到以下错误:

pickle.PicklingError: Can't pickle <class '__main__.P'>: it's not found as __main__.P

我发现如果我运行代码而不将其包装在函数中,它可以完美运行。包装在函数中时是否需要额外的步骤来 pickle 对象?

这是我的代码:
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)
    f = open('abe.pickle', 'w')
    pickle.dump(abe, f)
    f.close()

pickle_test()

最佳答案

在函数外创建命名元组:

from collections import namedtuple
import pickle

P = namedtuple("P", "one two three four")

def pickle_test():
    my_list = []
    abe = P("abraham", "lincoln", "vampire", "hunter")
    my_list.append(abe)
    f = open('abe.pickle', 'w')
    pickle.dump(abe, f)
    f.close()

pickle_test()

现在 pickle 可以找到了;它现在是一个全局模块。解压时,pickle 模块要做的就是再次定位 __main__.P。在您的版本中, Ppickle_test() 函数的本地函数,并且不可内省(introspection)或不可导入。

重要的是要记住 namedtuple() 是一个类工厂;你给它参数,它返回一个类对象供你创建实例。 pickle 只存储实例中包含的数据,加上对原始类的字符串引用以再次重建实例。

关于python - 如何正确 pickle 一个命名元组实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16377215/

10-14 01:12