按照建议 here ,我的包(或包含我的模块的目录)位于 C:/Python34/Lib/site-packages。该目录包含一个 __init__.pysys.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/

10-12 22:12