2017-02-02 7 views
3

Python 2.7のnamedtuple実装では、__dict__が実装されています。私はこれが何をしているのか混乱しています。既にプロパティが定義されている場合、特別なものを作る必要があるのはなぜですか?__dict__なぜPython 2.7のnamedtupleは__dict__を実装していますか?

C:\tmp> python 
Python 2.7.12 |Anaconda 4.1.1 (64-bit)| (default, Jun 29 2016, 11:07:13) [MSC v.1500 64 bit (AMD64)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
Anaconda is brought to you by Continuum Analytics. 
Please check out: http://continuum.io/thanks and https://anaconda.org 
>>> import collections 
>>> x = collections.namedtuple('foo','bar baz', verbose=True) 
class foo(tuple): 
    'foo(bar, baz)' 

    __slots__ =() 

    _fields = ('bar', 'baz') 

    def __new__(_cls, bar, baz): 
     'Create new instance of foo(bar, baz)' 
     return _tuple.__new__(_cls, (bar, baz)) 

    @classmethod 
    def _make(cls, iterable, new=tuple.__new__, len=len): 
     'Make a new foo object from a sequence or iterable' 
     result = new(cls, iterable) 
     if len(result) != 2: 
      raise TypeError('Expected 2 arguments, got %d' % len(result)) 
     return result 

    def __repr__(self): 
     'Return a nicely formatted representation string' 
     return 'foo(bar=%r, baz=%r)' % self 

    def _asdict(self): 
     'Return a new OrderedDict which maps field names to their values' 
     return OrderedDict(zip(self._fields, self)) 

    def _replace(_self, **kwds): 
     'Return a new foo object replacing specified fields with new values' 
     result = _self._make(map(kwds.pop, ('bar', 'baz'), _self)) 
     if kwds: 
      raise ValueError('Got unexpected field names: %r' % kwds.keys()) 
     return result 

    def __getnewargs__(self): 
     'Return self as a plain tuple. Used by copy and pickle.' 
     return tuple(self) 

    __dict__ = _property(_asdict) 

    def __getstate__(self): 
     'Exclude the OrderedDict from pickling' 
     pass 

    bar = _property(_itemgetter(0), doc='Alias for field number 0') 

    baz = _property(_itemgetter(1), doc='Alias for field number 1') 
+0

これは '__slots__'を持っているためです。明示的に定義していなければ、 '__dict__'はありません。 – jonrsharpe

+0

なぜ '__dict__'が必要ですか? (どの機能がそれを使いますか?) –

+3

'' __dict__''の使用は間違いでした。目標は "vars(nt)"を動作させることでしたが、Python 3では予期しない副作用があり、Python 3では完全に機能しませんでした。その結果、Python 3以降のバージョンから完全に削除されました。 '' _asdict''メソッドを使うと幸せになれます:-) –

答えて

3

彼らはそれが便利だろうと考えていました。それがmore hassle than it was worthだったことが判明し、酸洗いやサブクラスに問題を引き起こし、とにかく概念的に混乱していました。最近のPythonのバージョンではそれ以上はありません。

+0

'namedtuple'に似たようなことをしているのなら、' __dict__'の代入をスキップできますか?もし私がすれば、どのような特徴が見逃されますか? –

+1

@ JasonS:あなたはそれをスキップすることができます。混乱を正当化するのに十分な利益をもたらしたことはありませんでした。明白なことは、 'yourobject .__ dict__'はAttributeErrorを発生させますが、' yourobject._asdict() 'はその機能を得るためのより良い方法です。 – user2357112

+0

これは '__getstate__'メソッドにも当てはまりますか? –

関連する問題