簡體   English   中英

從實例中查找屬性

[英]Look up an attribute from an instance

從Python總結

從實例獲取屬性

當您使用語法x.name來引用類C的實例x的屬性時,查找將分三個步驟進行:

  1. name中發現C (或在一個C的祖先類)作為首要的描述符的名稱v (即, type(v)供給方法__get____set__

    x.name的值是type(v).__get__(v, x, C)的結果type(v).__get__(v, x, C)

  2. 否則,當namex.__dict__的鍵時

    x.name獲取並返回x.__dict__['name']

  3. 否則, 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. 步驟1和步驟3的第一部分是否相同? 如果是,為什么同一步驟出現兩次?

  2. 難道他們都發生“在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM