2017-02-02 1 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)"를 작동시키는 것이었지만, 피클 링에 예상치 못한 부작용이 있었으며 파이썬 3에서는 완전히 작동하지 않았습니다. 그 결과, 파이썬 3의 이후 버전에서 완전히 제거되었습니다. ''_asdict'' 메소드를 사용하면 행복하게 될 것입니다 :-) –

답변

3

방금 ​​편리하다고 생각했습니다. 그것이 절어와 하위 클래스에 문제를 일으키는 것은 more hassle than it was worth이었고, 어쨌든 개념적으로 혼란 스러웠습니다. 최근의 Python 버전에는 더 이상 필요하지 않습니다.

+0

그래서'namedtuple'과 비슷한 것을하고 있다면'__dict__' 과제를 건너 뛰어도 될까요? 내가 그렇게한다면, 나는 무엇을 놓치겠습니까? –

+1

@ JasonS : 건너 뛸 수 있습니다. 혼란을 정당화하기에 충분한 이익을 제공하지 못했습니다. 당신이 놓치게 될 분명한 사실은'yourobject .__ dict__'가 AttributeError를 발생시키지 만'yourobject._asdict()'가 그 기능을 얻는 더 좋은 방법이라는 것입니다. – user2357112

+0

그것은'__getstate__' 메소드에도 적용됩니까? –

관련 문제