簡體   English   中英

python子類訪問父類的類變量

[英]python subclass access to class variable of parent

得知子類的類變量無法訪問父類的類變量而沒有特別指出父類的名稱,我感到很驚訝:

>>> class A(object):
...     x = 0
... 
>>> class B(A):
...     y = x+1
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in B
NameError: name 'x' is not defined
>>> class B(A):
...     y = A.x + 1
... 
>>> B.x
0
>>> B.y
1

為什么在定義By中,我必須引用Ax,而不僅僅是x? 這與我對實例變量的直覺是相反的,並且因為在定義B之后我可以引用Bx。

Python的裸名作用域規則非常簡單明了:首先是本地名稱空間,然后是(如果有的話)外部函數(在其中嵌套當前函數),然后是全局函數,最后是內置函數。 查找裸名時,所有這些都將發生,並且無需記住或應用任何復雜的規則(也無需使用Python編譯器來執行更復雜的規則)。

每當您想要進行不同的查找時,都將使用限定名稱而不是名。 合格名稱的功能要強大得多,因為查找始終可以委托給可以請求其屬性的對象,並且這些對象可以實現所需的任何查找規則。 特別是,在一個類中的實例方法, self.x是問 self對象查找屬性名稱'x' -並且在查找它可以委托給類,包括繼承的概念的實施(以及多重繼承,方法解析順序等)。

類的主體 (與類中定義的方法的主體相對) 創建類對象或綁定其名稱之前(特別是在定義任何基礎之前)作為class語句的一部分執行作為基礎-盡管在提及裸名時,無論如何最新的細節都沒關系!

因此,在您的示例中,在類B ,使用通用規則查找裸名x -它是在本地綁定的名稱嗎? 如果否,是否將其綁定到嵌套此作用域的任何外部函數中? 如果不是,是綁定為全局對象還是內置對象? 如果以上都不是,則使用有問題的裸名當然會導致名稱錯誤異常。

由於您想要的查找順序與裸名查找規則普遍執行的查找順序不同,因此顯然您需要使用限定名,而不是裸名; 片刻的反思將清楚地表明,“一個顯而易見的選擇”為一名合格的名稱來使用你的目的必須是Ax -因為你希望它要查找(基地沒有在任何地方記錄是的那一點,畢竟……將是通常為type的元類,當在類體執行完之后被調用時,它將作為其工作的一部分進行鹼基綁定!

有些人非常熱衷於查找裸名的其他“魔術”規則,以至於他們忍受不了Python的這一方面(我相信,最初是受Modula-3啟發,這是一種鮮為人知的語言,在理論學家中已經考慮過了';;-)-必須在方法中編寫self.x來指定必須在self上查找x ,而不是使用通用裸名規則,例如,使此類人發胖。

我,我喜歡裸名查找規則的簡單性和通用性,並且我喜歡在需要任何其他形式的查找的任何時間使用合格名稱而不是裸名...但是,我瘋狂地愛上它並不是一個秘密Python(我有自己的抱怨-例如, global x總是使我的皮膚爬行,我更願意在其中編寫global.x ,即讓global成為“當前執行模塊”的內置名稱...我確實喜歡合格的名字!-),對嗎?-)

在Python中,在創建類之前,將在其自己的名稱空間中執行類的主體(此后,該名稱空間的成員將成為該類的成員)。 因此,當解釋器達到y = x + 1時,此時B類還不存在,因此沒有父類。

有關更多詳細信息,請參見http://docs.python.org/reference/compound_stmts.html#class-definitions

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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