【问题标题】:Pickle: AttributeError: 'module' object has no attributePickle:AttributeError:“模块”对象没有属性
【发布时间】:2013-02-13 13:43:25
【问题描述】:

我发现了很多关于此的线程,但所有线程的问题都是命名空间。我的问题与命名空间无关。

一个小例子:

import cPickle as pickle
from uncertainties import Variable

class value(Variable):
    def __init__(self, args, showing=False):
        self.show = showing
        Variable.__init__(self, args[0], args[1])

val = value((3,1), True)
print val.nominal_value, val.std_dev(), val.show
fobj = file("pickle.file", "w")
pickle.dump(val, fobj)
fobj.close()

fobj = file("pickle.file", "r")
val = pickle.load(fobj)
fobj.close()
print val.nominal_value, val.std_dev(), val.show

这段代码的输出:

3.0 1.0 True
3.0 1.0
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/usr/lib/python2.7/dist-packages/IPython/utils/py3compat.pyc in execfile(fname, *where)
    173             else:
    174                 filename = fname
--> 175             __builtin__.execfile(filename, *where)

/home/markus/pickle.py in <module>()
     19 val = pickle.load(fobj)
     20 fobj.close()
---> 21 print val.nominal_value, val.std_dev(), val.show

AttributeError: 'value' object has no attribute 'show'

命名空间在酸洗和解酸时是相同的。 uncertainties.Variable 的所有属性都已恢复 - 只有我添加的一个“节目”丢失了。

【问题讨论】:

  • uncertainties 模块是什么?它来自哪里?
  • 你能想出一个独立的例子吗,即我们可以试验的例子?
  • @NPE:一旦找到uncertainties project,我就能重现它;它使用自定义的__getstate__ 方法。
  • 我不允许以新用户身份发布链接。但我在原始 python.org 页面上找到了这个模块:pypi.python.org/pypi/uncertainties

标签: python attributeerror pickle


【解决方案1】:

uncertainties.Variable() class 使用__slots__ attribute 来节省内存。因此,为了可腌制,它必须定义一个__getstate__ method(参见Why am I getting an error about my class defining __slots__ when trying to pickle an object?)。

如果您需要添加自己的附加属性,则必须覆盖 __getstate__ 方法。在您自己的 __slot__ 属性中声明您的附加属性可能也是一个好主意:

from uncertainties import Variable

class value(Variable):
    __slots__ = ('show',)  # only list *additional* slots

    def __init__(self, args, showing=False):
        self.show = showing
        super(value, self).__init__(args[0], args[1])

    def __getstate__(self):
        obj_slot_values = {}
        for cls in type(self).mro():
            obj_slot_values.update((k, getattr(self, k)) for k in getattr(cls, '__slots__', ()))
        # Conversion to a usual dictionary:
        return obj_slot_values

这个新的__getstate__ 是必需的,因为Variable.__getstate__ 方法假定只有一个 __slots__ 属性,而MRO 中的每个类都可能有一个。

这确实是uncertainties 库的限制;我已经提交了一个 pull request 来解决这个问题,并且不需要在子类中覆盖 __getstate__ 方法。

【讨论】:

  • 好的,“简单”的方式,但很难用这个一般的 AttributeError 找到。非常感谢。
  • @Chickenmarkus:感谢 Martijn,他给我发了一个补丁,最新的 Github 版本的不确定性让你的 value 类可以直接选择,而无需定义你自己的 __getstate__()
  • @Chickenmarkus:我刚刚上传了我的不确定性包 (pypi.python.org/pypi/uncertainties) 的 1.9.1 版:您的子类现在应该可以直接腌制了(无需定义您自己的 __getstate__
  • @EOL:是的,在 1.9.1 版本中,我的第一个示例现在也可以使用。谢谢。
猜你喜欢
  • 2017-03-29
  • 2010-11-18
  • 2019-01-03
  • 2017-05-19
  • 2013-02-01
  • 2018-02-27
  • 2016-05-04
  • 2011-01-30
相关资源
最近更新 更多