我正在尝试腌制在脚本中生成的对象以便随后处理它们,但我收到此错误:
File "<ipython-input-2-0f716e86ecd3>", line 1, in <module>
pickle.dump(thisperson, output, pickle.HIGHEST_PROTOCOL)
RecursionError: maximum recursion depth exceeded while pickling an object
这里
thisperson
相对简单(或者我是这么认为的):一个名字和一个包含属性的字典:
class Attributes:
def __init__(self, what_attr, attr):
self._what_attr = what_attr
self._attributes = attr
@property
def what_attr(self):
return self._what_attr
@what_attr.setter
def what_attr(self, new_value):
self._what_attr = new_value
@property
def attributes(self):
return self._attributes
@attributes.setter
def attributes(self, new_value):
self._attributes = new_value
class Person:
def __init__(self, watname, watage):
self._myname = watname
self._age = watage
self._attributes = []
@property
def attributes(self):
return self._attributes
@attributes.setter
def attributes(self, attributes_list):
self._attributes = attributes_list
@property
def myname(self):
return self._myname
@myname.setter
def myname(self, value):
self._myname = value
@property
def age(self):
return self._age
@age.setter
def age(self, value):
self._age = value
pickle 函数如下所示:
import pickle
def save_person(person, mypath):
import os
if not os.path.exists(mypath):
os.makedirs(mypath)
my_path = mypath + str(person.myname)
if not os.path.exists(my_path + '/'):
os.makedirs(my_path + '/')
with open(my_path + '.pkl', 'wb') as output:
pickle.dump(person, output, pickle.HIGHEST_PROTOCOL)
这个错误似乎是由于该类包含一个字符串和一个
dict
的事实,因为如果我将属性保留为空 dict
我不会收到错误。
还有其他方法可以腌制这些物体吗?
我尝试增加
sys.setrecursionlimit
,但这没有帮助。
编辑: ....如果我使用简短版本的代码,我无法重现该错误....想想看。 @MinhNguyen 奇怪的是,我在函数中创建属性字典(attr = get_attributes(data)),但是当我自己创建相同的字典时,我可以腌制它....
thisperson = Person("Kenny", 22, {})
attr = get_attributes(data) # returns {'eyes': 'blue', 'hair': 'brown'}
this_attr = Attributes(person_name, attr)
this_person.attributes.append(this_attr)
save_person(this_person, main_folder)
Exception ignored in:
'_pydevd_frame_eval.pydevd_frame_evaluator_win32_37_64.get_bytecode_while_frame_eval'
RecursionError: maximum recursion depth exceeded while calling a Python object
Process finished with exit code -1073741819 (0xC0000005)
但是如果我执行以下操作,它就会起作用:
attr = {'eyes': 'blue', 'hair': 'brown'}
this_attr = Attributes(person_name, attr)
this_person.attributes.append(this_attr)
save_person(this_person, main_folder)
好吧,经过进一步挖掘,我发现herepickle 与 dict 不能很好地混合,并且经常会崩溃。
所以解决方法是我完全删除了 Attribute 类,现在我的 Person 的 _attribute 是一串 dict self._attributes = str(dict()) 每当我想向其中添加内容时,我都会这样做再次 eval()、update() 和 str()。
到目前为止这似乎有效......
我一直在使用
concurrent.futures
模块,特别是 ProcessPoolExecutor
类,它使用(在幕后)pickle
模块将值返回到主进程。
这个问题是,当我们谈论嵌套的东西时,pickle
模块似乎对你可以“pickle-ize”的东西有限制。就我而言,我的结构如下:
data = [
{
"string_list": [
["a1", "a2", ..., "an"],
["b1", "b2", ..., "bn"],
...
["n1", "n2", ..., "nn"],
]
},
{
"string_list": [
["a1", "a2", ..., "an"],
["b1", "b2", ..., "bn"],
...
["n1", "n2", ..., "nn"],
]
},
基本上,它是一个字典列表,每个字典都包含一个字符串列表的列表。我的意思是,这是一个相对嵌套的结构。每次我尝试从
data
结果中获取 ProcessPoolExecutor's
时,它都会引发 RecursionError: maximum recursion depth exceeded while pickling an object
,这是由于 pickle 模块(显然)无法处理这种级别的嵌套。
我的解决方案与编辑的问题中提供的类似。我在酸洗之前“串化”了结构,然后在可以访问
data
后撤消它。就我个人而言,我使用了 json 模块,该模块还附带了 Python 标准库。
这是我处理pickle模块的“经验”。
快速评论:我发现对于我的对象,IntEnum 导致了这个。有一个它的实例,用一堆常量替换它,异常就消失了。