您正在保存所有顾客实例(即self
)到Patron
类属性Patron.patrons
。然后您尝试从类中pickle 类属性。这会让人窒息pickle
,然而我相信dill
应该能够应付。是否真的有必要将所有类实例保存到 Patrons 的列表中?这样做有点奇怪……
pickle
通过引用序列化类,并且不能很好地使用__main__
对于许多物体。在dill
,您不必通过引用序列化类,并且它可以处理以下问题__main__
, 好多了。得到dill
here: https://github.com/uqfoundation https://github.com/uqfoundation
Edit:我尝试了你的代码(做了一个小小的更改)并且它有效。
dude@hilbert>$ python patronmaker.py
然后启动Python...
>>> import dill
>>> f = open('patrons.pkl', 'rb')
>>> p = dill.load(f)
>>> p
[Julius Caeser, Kunte Kinta, Norton Henrich, Mother Teresa]
我所做的唯一更改是取消注释末尾的行patronmaker.py
这样它就拯救了一些顾客……我也更换了import pickle
with import dill as pickle
到处。
因此,即使通过下载并运行您的代码,我也不会产生错误dill
。我用的是最新的dill
来自github。
附加编辑:您上面的回溯来自ImportError
。你安装你的模块了吗?如果您没有使用 setup.py 来安装它,或者您的模块上没有PYTHONPATH
,那么无论您如何序列化事物,您都找不到您的模块。
更多编辑:查看您的代码,您应该使用单例模式 for patrons
…它不应该在里面class Patron
。类级别的代码块,用于将顾客加载到其中Patron.patrons
肯定会引起问题……并且可能必然是某种形式错误的根源。我还看到你正在酸洗属性Patrons.patrons
(甚至不是类本身)从内部Patrons
班级 -这太疯狂了——别这样做。另请注意,当您尝试获得订阅会员时,您可以使用Patron.patrons
…这是调用类对象而不是实例。将订阅者移到类之外,并直接使用单例作为订阅者列表。此外,您通常应该使用顾客实例,因此如果您想让每个顾客知道所有其他顾客是谁,p = Patron('Joe', 'Blow')
, then p.patrons
得到所有顾客......但你需要写一个Patrons.load
读取单例顾客列表的方法......你也可以使用property
使load
给你一些看起来像属性的东西。
如果您构建一个单一的顾客(作为列表)......或者如果您愿意的话,建立一个顾客“注册表”(作为字典),那么只需检查顾客pickle文件是否存在......加载到注册表......并且不要这样做从赞助人班级内部开始……事情应该会好得多。您的代码当前正在尝试在类定义上加载类实例,而它builds那个类对象。那很糟...
另外,当您没有提供最小的测试用例或有关如何创建回溯的足够信息时,不要指望人们会下载您的代码并为您调试。
你may遇到了有效的酸洗错误dill
对于一些黑暗的角落情况,但我不能告诉 b/c 我无法重现你的错误。但是,我可以看出您需要一些重构。
明确地说:
将您的顾客初始化混乱从顾客转移到新文件中patrons.py
import os
import dill as pickle
#Initialize patrons with saved pickle data
if os.path.isfile('patrons.pkl'):
with open("patrons.pkl", 'rb') as f:
patrons = pickle.load(f)
else: patrons = []
然后在 pattonmaker.py 中,以及其他任何你需要单例的地方......
import dill as pickle
import os.path
import patrons as the
class Patron:
def __init__(self, lname, fname):
self.lname = lname.title()
self.fname = fname.title()
self.terrCheckedOutHistory = {}
#Add any created Patron to patrons list
the.patrons.append(self)
#Preserve this person via pickle
with open('patrons.pkl', 'wb') as f:
pickle.dump(the.patrons, f)
除非您的代码遇到模块上的属性无法序列化的情况之一,否则您应该没问题,因为它们是动态添加的(请参阅https://github.com/uqfoundation/dill/pull/47 https://github.com/uqfoundation/dill/pull/47),这绝对应该使pickle
失败,并且在某些情况下dill
太……可能有一个AtrributeError
在模块上。我只是无法重现这个……我已经完成了。