web-dev-qa-db-ja.com

3.5.1で `namedtuple`について何か変更がありましたか?

オン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()に関する何かでしたか?)。

これは意図的なものでしたか?名前付きタプルを辞書に変換するためにこのパターンを使用することはもうありませんか?

34
Nick Chammas

あたり Pythonバグ#24931

[___dict___]はPython 3で根本的に壊れていたため、削除する必要がありました。___dict___を提供すると、サブクラスが壊れ、奇妙な動作が発生しました。

変更を加えた改訂

具体的には、___slots___が定義されていないサブクラスは奇妙な動作をします。

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

._asdict()を使用します。

31
ShadowRanger

docs から

名前付きタプルインスタンスにはインスタンスごとの辞書がないため、軽量であり、通常のタプルよりも多くのメモリを必要としません。

docs (およびhelp(namedtuple))は、c._asdict()を使用してdictに変換すると言います。

9
Chad S.

__dict__@propertyとして実装され、削除されました。ソースコードの変更を確認できます。

.5.

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

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