Oin
Oin

Reputation: 7529

_asdict in Python 3 namedtuple subclass returns empty dictionary

How can I use _asdict from a Python 3 subclass of namedtuple?

This is what I've tried:

class A(namedtuple('B', 'c')):
    pass

a = A(3)

a._asdict()
{}

This works fine in Python 2 and returns:

OrderedDict([('c', 3)])

Upvotes: 4

Views: 7615

Answers (3)

Rupert Angermeier
Rupert Angermeier

Reputation: 1015

This seems to be a bug with Python 3.x that has been resolved somewhere between 3.4.2 and 3.4.5.

To get _asdict() working on affected versions set __slots__ = () on your class:

class A(namedtuple('B', 'c')):
    __slots__ = ()

Upvotes: 0

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160567

As I found out, this behavior was listed as a bug in Issue 24931 and fixed. The correct behavior is present in version 3.5.2 (Python 2.x was not affected by this.)

Using my current version of Python (3.5.2) this performs as expected:

class A(namedtuple('B', 'c')): 
    pass

A(3)._asdict()
Out[7]: OrderedDict([('c', 3)])

So, in short, either consider updating to 3.5.1+ or, if you cannot, implement _asdict yourself; this is stated in a message on the issue tracker and seems like a viable alternative:

from collections import namedtuple, OrderedDict

class A(namedtuple('B', 'c')):
    def _asdict(self):
        return OrderedDict(zip(self._fields, self))

behaves as you need.

Upvotes: 8

infotoni91
infotoni91

Reputation: 721

You have to import namedtuple from collections. Tested with Python 3.5.2:

>>> from collections import namedtuple
>>>
>>> class A(namedtuple('B', 'c')):
...     pass
...
>>> a = A(3)
>>>
>>> a._asdict()
OrderedDict([('c', 3)])

What do you expect from the empty dictionary at the end?

>>> {}
{}

Upvotes: 0

Related Questions