我正在学习如何使用咸菜。 我创建了一个namedtuple对象时,它添加到列表中,并试图咸菜该列表。 不过,我得到以下错误:
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)
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
一次。 在您的版本, P
是本地人 ,对pickle_test()
函数,而不是内省或可导入。
一定要记住这一点很重要namedtuple()
是一类厂; 你给它的参数和返回供您创建实例的类对象。 pickle
只存储包含在所述实例中的数据 ,再加上一个字符串引用原始类再次重建实例。
之后,我将我的问题,即主要答复评论我找到了一种方法来解决使动态创建的问题namedtuple
咸菜,能。 这是需要在我的情况,因为我搞清楚它的领域仅在运行时(后DB查询)。
我要做的就是猴子修补 namedtuple
通过有效地将其移动到__main__
模块:
def _CreateNamedOnMain(*args):
import __main__
namedtupleClass = collections.namedtuple(*args)
setattr(__main__, namedtupleClass.__name__, namedtupleClass)
namedtupleClass.__module__ = "__main__"
return namedtupleClass
记住, namedtuple
名称(这是由提供args
)可能会覆盖另一个成员在__main__
如果你不小心。
另外,您也可以使用cloudpickle
或dill
序列化:
from collections import namedtuple
import cloudpickle
import dill
def dill_test(dynamic_names):
P = namedtuple('P', dynamic_names)
my_list = []
abe = P("abraham", "lincoln", "vampire", "hunter")
my_list.append(abe)
with open('deleteme.cloudpickle', 'wb') as f:
cloudpickle.dump(abe, f)
with open('deleteme.dill', 'wb') as f:
dill.dump(abe, f)
dill_test("one two three four")
我发现这个答案在另一个线程。 这是所有关于命名元组的命名。 这为我工作:
group_t = namedtuple('group_t', 'field1, field2') # this will work
mismatched_group_t = namedtuple('group_t', 'field1, field2') # this will throw the error
这里的问题是子进程无法导入对象的类-in这种情况下,类P-,在多模式项目的情况下,P类应该是导入的任何地方习惯的子进程
一个快速的解决方法是使其可导入由它影响到全局变量()
globals()["P"] = P