Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Can't pickle type X, attribute lookup failed

Tags:

python

pickle

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.)

like image 524
Nick Heiner Avatar asked Jan 13 '11 05:01

Nick Heiner


1 Answers

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.

like image 105
Amber Avatar answered Sep 26 '22 14:09

Amber