python - example - ¿Algo sobre `namedtuple` cambió en 3.5.1?
python dict (3)
De los docs
Las instancias de tuplas nombradas no tienen diccionarios por instancia, por lo que son livianas y no requieren más memoria que las tuplas normales.
Los docs (y la help(namedtuple)
) dicen que se use c._asdict()
para convertir a un dict.
En 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)])
En 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
Parece que algo sobre namedtuple
cambió (o tal vez fue algo sobre vars()
?).
¿Fue esto intencional? ¿No se supone que debemos usar este patrón para convertir tuplas con nombres en diccionarios más?
Por error de Python # 24931 :
[
__dict__
] desapareció porque estaba fundamentalmente roto en Python 3, por lo que tuvo que ser eliminado. Proporcionar__dict__
rompió las subclases y produjo comportamientos extraños.
Específicamente, las subclases sin __slots__
definidas se comportarían de manera extraña:
>>> Cluster = namedtuple(''Cluster'', ''x y'')
>>> class Cluster2(Cluster):
pass
>>> vars(Cluster(1,2))
OrderedDict([(''x'', 1), (''y'', 2)])
>>> vars(Cluster2(1,2))
{}
Use ._asdict()
.
__dict__
se implementó como @property
y se ha eliminado; puedes ver el cambio en el código fuente:
3.5.0 :
def __repr__(self):
''Return a nicely formatted representation string''
return self.__class__.__name__ + ''({repr_fmt})'' % self
@property
def __dict__(self):
''A new OrderedDict mapping field names to their values''
return OrderedDict(zip(self._fields, self))
def _asdict(self):
''Return a new OrderedDict which maps field names to their values.''
return self.__dict__
def __getnewargs__(self):
''Return self as a plain tuple. Used by copy and pickle.''
return tuple(self)
def __getstate__(self):
''Exclude the OrderedDict from pickling''
return None
3.5.1 :
def __repr__(self):
''Return a nicely formatted representation string''
return self.__class__.__name__ + ''({repr_fmt})'' % self
def _asdict(self):
''Return a new OrderedDict which maps field names to their values.''
return OrderedDict(zip(self._fields, self))
def __getnewargs__(self):
''Return self as a plain tuple. Used by copy and pickle.''
return tuple(self)