[英]Look up an attribute from an instance
從Python總結
從實例獲取屬性
當您使用語法
x.name
來引用類C
的實例x
的屬性時,查找將分三個步驟進行:
當
name
中發現C
(或在一個C
的祖先類)作為首要的描述符的名稱v
(即,type(v)
供給方法__get__
和__set__
)•
x.name
的值是type(v).__get__(v, x, C)
的結果type(v).__get__(v, x, C)
否則,當
name
是x.__dict__
的鍵時•
x.name
獲取並返回x.__dict__['name']
否則,
x.name
將查找委托給x
的類(根據剛才用於C.name
的相同的兩步查找,C.name
)• 找到描述符
v
,屬性查找的總體結果再次是type(v).__get__(v, x, C)
•找到非描述符值
v
時,屬性查找的總結果為v
當這些查找步驟找不到屬性時,Python會引發
AttributeError
異常。 但是,對於x.name
查找,當C
定義或繼承特殊方法__getattr__
,Python會調用C.__getattr__(x,'name')
而不是引發異常。 然后由__getattr__
決定是否返回合適的值或引發合適的異常,通常是AttributeError
。
步驟1和步驟3的第一部分是否相同? 如果是,為什么同一步驟出現兩次?
難道他們都發生“在name
中找到C
(或者在一個C
的祖先類)作為壓倒一切的描述符的名字v
”?
__getattribute__(self, name)
在每次訪問屬性
xy
請求時,Python都會調用x.__getattribute__('y')
,后者必須獲取並返回屬性值,否則會引發AttributeError
。 屬性訪問的常規語義(使用x.__dict__
C.__slots__
,C.__slots__
,C
的類屬性x.__getattr__
)都歸因於object.__getattribute__
。 當類C
覆蓋__getattribute__
,它必須實現它要提供的所有屬性訪問語義。 通常,實現屬性訪問語義的最方便的方法是通過委派(例如,調用object.__getattribute__(self, ...)
作為覆蓋__getattribute__
的操作的一部分)。
步驟1和步驟3的第一部分是否相同? 如果是,為什么同一步驟出現兩次?
步驟1同時需要__get__
和__set__
(盡管實際上, __set__
或__delete__
以及__get__
都會觸發它)。 如果在步驟1或2中找不到屬性,則將無條件執行步驟3。
它們都發生“當在C(或C的祖先類之一)中找到名稱作為重載描述符v的名稱時”嗎?
否。“覆蓋描述符”觸發步驟1; 在步驟3中將只考慮另一種描述符或非描述符。(官方Python文檔不使用術語“覆蓋描述符”;它們將帶有__set__
或__delete__
的描述符稱為“數據描述符”,並且如果數據描述符具有__get__
,則__get__
將優先於實例字典中找到的對象。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.