Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Did something about `namedtuple` change in 3.5.1?

On Python 3.5.0:

>>> from collections import namedtuple >>> cluster = namedtuple('Cluster', ['a', 'b']) >>> c = cluster(a=4, b=9) >>> c Cluster(a=4, b=9) >>> vars(c) OrderedDict([('a', 4), ('b', 9)]) 

On Python 3.5.1:

>>> from collections import namedtuple >>> cluster = namedtuple('Cluster', ['a', 'b']) >>> c = cluster(a=4, b=9) >>> c Cluster(a=4, b=9) >>> vars(c) Traceback (most recent call last):   File "<stdin>", line 1, in <module> TypeError: vars() argument must have __dict__ attribute 

Seems like something about namedtuple changed (or maybe it was something about vars()?).

Was this intentional? Are we not supposed to use this pattern for converting named tuples into dictionaries anymore?

like image 991
Nick Chammas Avatar asked Dec 08 '15 21:12

Nick Chammas


People also ask

When can you change the value of a Namedtuple?

Since a named tuple is a tuple, and tuples are immutable, it is impossible to change the value of a field.

What's the advantage of using Namedtuple instead of tuple?

Namedtuple makes your tuples self-document. You can easily understand what is going on by having a quick glance at your code. And as you are not bound to use integer indexes to access members of a tuple, it makes it more easy to maintain your code.

Should I use Namedtuple?

In general, you can use namedtuple instances wherever you need a tuple-like object. Named tuples have the advantage that they provide a way to access their values using field names and the dot notation. This will make your code more Pythonic.

What is the difference between tuple and Namedtuple?

Tuples are immutable, whether named or not. namedtuple only makes the access more convenient, by using names instead of indices. You can only use valid identifiers for namedtuple , it doesn't perform any hashing — it generates a new type instead.


1 Answers

Per Python bug #24931:

[__dict__] disappeared because it was fundamentally broken in Python 3, so it had to be removed. Providing __dict__ broke subclassing and produced odd behaviors.

Revision that made the change

Specifically, subclasses without __slots__ defined would behave weirdly:

>>> Cluster = namedtuple('Cluster', 'x y') >>> class Cluster2(Cluster):     pass >>> vars(Cluster(1,2)) OrderedDict([('x', 1), ('y', 2)]) >>> vars(Cluster2(1,2)) {} 

Use ._asdict().

like image 108
ShadowRanger Avatar answered Oct 07 '22 12:10

ShadowRanger