我正在尝试腌制namedtuple:
namedtuple
from collections import namedtuple import cPickle class Foo: Bar = namedtuple('Bar', ['x', 'y']) def baz(self): s = set() s.add(Foo.Bar(x=2, y=3)) print cPickle.dumps(s) if __name__ == '__main__': f = Foo() f.baz()
这将产生以下输出:
Traceback (most recent call last): File "scratch.py", line 15, in <module> f.baz() File "scratch.py", line 11, in baz print cPickle.dumps(s) cPickle.PicklingError: Can't pickle <class '__main__.Bar'>: attribute lookup __main__.Bar failed
我究竟做错了什么?是,这个问题Bar是一个成员Foo?(将的定义Bar移到最高级别可以解决此问题,尽管我仍然很好奇为什么会这样。)
Bar
Foo
是的,它是类成员这一事实是一个问题:
>>> class Foo(): ... Bar = namedtuple('Bar', ['x','y']) ... def baz(self): ... b = Foo.Bar(x=2, y=3) ... print(type(b)) ... >>> a = Foo() >>> a.baz() <class '__main__.Bar'>
问题在于,当namedtuple()返回类型对象时,它不知道将其分配给类成员的事实- 因此,它告诉类型对象其类型名称应为__main__.Bar,即使它确实应该为__main__.Foo.Bar。
namedtuple()
__main__.Bar
__main__.Foo.Bar