I am trying to pickle a 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()
This produces the following output:
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
What am I doing wrong? Is the problem that Bar
is a member of Foo
? (Moving the definition of Bar
to the top level solves the problem, although I'm still curious why this happens.)
Yes, the fact that it's a class member is a problem:
>>> 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'>
The problem is that when namedtuple()
returns a type object, it isn't aware of the fact that it's being assigned to a class member - and thus, it tells the type object that its type name should be __main__.Bar
, even though it should really be __main__.Foo.Bar
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With