2013-02-28 27 views
6

在下面的示例中,屬性x從對象的槽訪問即使x存在於__dict__(這不是典型的或可能有用的情況下,但我很好奇):Python中的屬性訪問:第一個插槽,然後__dict__?

>>> class C(object): 
...  __slots__ = 'x' 
...  
>>> class D(C): 
...  pass 
... 
>>> obj = D() 
>>> obj.x = 'Stored in slots' 
>>> obj.__dict__ 
{} 
>>> obj.__dict__['x'] = 'stored in __dict__' 
>>> obj.x 
'Stored in slots' 

是這個訪問順序(插槽第一個)是一個記錄的行爲?或者只是一個實現細節?

回答

10

是的,__dict__一個對象只有在諮詢了數據描述符之後才被查閱。 __slots__屬性被實現爲數據描述符。

參見Invoking descriptors

例如綁定,描述符調用的優先級取決於所定義的描述符的方法,其。描述符可以定義__get__()__set__()__delete__()的任意組合。如果它沒有定義__get__(),那麼訪問該屬性將返回描述符對象本身,除非對象的實例字典中有值。如果描述符定義了__set__()和/或__delete__(),它是一個數據描述符;如果它既不定義,它也是一個非數據描述符。通常,數據描述符定義了__get__()__set__(),而非數據描述符只有__get__()方法。定義了__set__()__get__()的數據描述符總是覆蓋實例字典中的重新定義。相反,非數據描述符可以被實例覆蓋。

,並從相同的頁面,section on slots

__slots__在通過爲每個變量名描述符(描述符實施)類級別被實現。因此,類屬性不能用於爲由__slots__定義的實例變量設置默認值;否則,類屬性會覆蓋描述符分配。

+0

我認爲這也應該引用(來自[Implementing Descriptors](http://docs.python.org/2/reference/datamodel.html#implementing-descriptors)):「描述符必須在所有者的類字典或父類之一的類字典中。 – 2013-02-28 15:29:30

+1

@PavelAnossov:不知道那會增加理解插槽。槽屬性被實現爲類中的描述符,數據描述符出現在實例'__dict__'值之前。這足以證明這種行爲,不是嗎? – 2013-02-28 15:32:09

+0

@PavelAnossov:是的,有時候人們會對描述符在哪裏查找感到困惑,但這不是問題。 – 2013-02-28 15:33:13

相關問題