按照建议 here ,我的包(或包含我的模块的目录)位于 C:/Python34/Lib/site-packages。该目录包含一个 __init__.py
,sys.path
包含目录的路径,如图所示。
我仍然收到以下错误:
Traceback (most recent call last):
File "C:/Python34/Lib/site-packages/toolkit/window.py", line 6, in <module>
from catalogmaker import Catalog
File "C:\Python34\Lib\site-packages\toolkit\catalogmaker.py", line 1, in <module>
from patronmaker import Patron
File "C:\Python34\Lib\site-packages\toolkit\patronmaker.py", line 4, in <module>
class Patron:
File "C:\Python34\Lib\site-packages\toolkit\patronmaker.py", line 11, in Patron
patrons = pickle.load(f)
ImportError: No module named 'Patron'
我在patronmaker.py 中有一个名为'Patron' 的类,但没有名为Patron 的模块,所以我不确定错误消息中的最后一条语句是什么意思。我非常感谢你对我所缺少的东西的想法。
Python 3.4.1 版 在 Windows 32 位机器上。
最佳答案
您将所有顾客实例(即 self
)保存到 Patron
类属性 Patron.patrons
。然后你试图从类中pickle一个类属性。这可能会阻塞 pickle
,但是我相信 dill
应该能够处理它。真的有必要将所有类实例保存到 Patrons 中的列表中吗?这样做有点奇怪……pickle
通过引用序列化类,并且对于许多对象不能很好地与 __main__
配合使用。在 dill
中,您不必通过引用序列化类,它可以更好地处理 __main__
的问题。在此处获取 dill
:https://github.com/uqfoundation
编辑:
我试过你的代码(有一个小改动)并且它起作用了。
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
替换了 import dill as pickle
。因此,即使通过下载并运行您的代码,我也无法使用
dill
产生错误。我正在使用来自 github 的最新 dill
。附加编辑:
您上面的回溯来自
ImportError
。你安装了你的模块吗?如果您没有使用 setup.py 来安装它,或者如果您的 PYTHONPATH
上没有您的模块,那么无论您如何序列化,您都不会找到您的模块。更多编辑:
查看您的代码,您应该对
patrons
使用 单例模式 ……它不应该在 class Patron
内。在类级别将顾客加载到 Patron.patrons
的代码块肯定会引起问题……并且可能必然是某种形式错误的根源。我还看到您正在从 Patrons.patrons
类内部 pickle 属性 Patrons
(甚至不是类本身)—— 这太疯狂了 ——不要这样做。还要注意,当你试图获得顾客时,你使用 Patron.patrons
......这是调用类对象而不是实例。将顾客移出类(class),并直接使用单例作为顾客列表。此外,您通常应该使用顾客实例,所以如果您想让每个顾客知道所有其他顾客是谁, p = Patron('Joe', 'Blow')
,然后 p.patrons
来获取所有顾客……但您需要编写一个 Patrons.load
方法来读取单例列表顾客……你也可以使用 property
来让 load
给你一些看起来像属性的东西。如果你建立一个单一的顾客(作为一个列表)……或者一个顾客的“登记”(作为一个字典),如果你愿意,那么只需检查一个顾客pickle文件是否存在……加载到登记处……不要这样做它来自赞助人类(class)……事情应该会好得多。您的代码当前正在尝试在构建类对象时在类定义上加载类实例。那很糟...
此外,不要指望人们去下载您的代码并为您调试它,当您没有提供最少的测试用例或关于如何创建回溯的足够信息时。
对于某些黑暗的角落情况,您可能在
dill
中遇到了有效的 pickle 错误,但我无法告诉 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 = []
然后在patronmaker.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 ),这肯定会使
pickle
失败,并且在某些情况下 dill
也是...... AtrributeError
在模块上。我只是无法重现这个……我已经完成了。关于python - 更多关于 python ImportError 没有命名的模块,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25236577/