`namedtuple` 在 3.5.1 中有什么变化吗?
Did something about `namedtuple` change in 3.5.1?
在 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)])
在 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
似乎 namedtuple
发生了变化(或者可能是 vars()
?)。
这是故意的吗?难道我们不应该再使用这种模式将命名元组转换为字典吗?
来自docs
Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples.
docs(和help(namedtuple)
)说要使用c._asdict()
转换成字典。
[__dict__
] disappeared because it was fundamentally broken in Python 3, so it had to be removed. Providing __dict__
broke subclassing and produced odd behaviors.
具体来说,没有定义 __slots__
的子类会表现得很奇怪:
>>> Cluster = namedtuple('Cluster', 'x y')
>>> class Cluster2(Cluster):
pass
>>> vars(Cluster(1,2))
OrderedDict([('x', 1), ('y', 2)])
>>> vars(Cluster2(1,2))
{}
使用._asdict()
.
__dict__
作为 @property
实现并已被删除;你可以在源代码中看到变化:
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
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)
在 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)])
在 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
似乎 namedtuple
发生了变化(或者可能是 vars()
?)。
这是故意的吗?难道我们不应该再使用这种模式将命名元组转换为字典吗?
来自docs
Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples.
docs(和help(namedtuple)
)说要使用c._asdict()
转换成字典。
[
__dict__
] disappeared because it was fundamentally broken in Python 3, so it had to be removed. Providing__dict__
broke subclassing and produced odd behaviors.
具体来说,没有定义 __slots__
的子类会表现得很奇怪:
>>> Cluster = namedtuple('Cluster', 'x y')
>>> class Cluster2(Cluster):
pass
>>> vars(Cluster(1,2))
OrderedDict([('x', 1), ('y', 2)])
>>> vars(Cluster2(1,2))
{}
使用._asdict()
.
__dict__
作为 @property
实现并已被删除;你可以在源代码中看到变化:
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
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)