[英]Attributes from superclass constructor in Python 3 on created or accessible?
我得到此回溯:
Traceback (most recent call last):
File "/home/amentis/Dropbox/Rexi/index.py", line 21, in application
ui = Console.Console()
File "/home/amentis/Dropbox/Rexi/UI/Console.py", line 9, in __init__
self.__window = Window.Window(self, 'consoleWindow')
File "/home/amentis/Dropbox/Rexi/RxAPI/RxGUI/Window.py", line 16, in __init__
self.__parent.add_child(self)
AttributeError: 'Window' object has no attribute '_Window__parent'
這是Console類的一部分:
class Console(Screen.Screen):
def __init__(self):
super().__init__("REXI Console")
self.__window = Window.Window(self, 'consoleWindow')
Window類的:
class Window(RxGUIObject.RxGUIObject):
def __init__(self, parent, name):
RxGUIObject.RxGUIObject.__init__(self, name, parent)
self.__body = ""
self.__javascript = ""
self.__css = ""
self.__parent.add_child(self)
和RxGUIObject:
class RxGUIObject(RxObject.RxObject):
def __init__(self, name, parent):
RxObject.RxObject.__init__(self, name)
self.__parent = parent
self.__children = list
Window.__parent
未創建或不存在,為什么?
您剛剛偶然發現python的名稱修改 。 以雙下划線開始,並在最多一個結尾下划線結束,喜歡你的每個屬性__parent
,被重命名為_ClassName__attributename
。
>>> class A(object):
... def __init__(self):
... self.__a = 1
...
>>> class B(A):
... pass
...
>>> b = B()
>>> b.__a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'B' object has no attribute '__a'
>>> b._A__a
1
為什么要這樣做? 為了防止子類化時屬性沖突。 特別是文檔指出:
由於存在類專用成員的有效用例(即避免名稱與子類定義的名稱發生名稱沖突 ),因此對這種稱為名稱修改的機制的支持有限。 形式為
__spam
任何標識符(至少兩個前導下划線,至多一個下划線)在文本上被_classname__spam
替換,其中classname
是當前的類名,其中前導下划線被去除。 只要不存在標識符的語法位置,就可以進行這種改寫,只要它出現在類的定義內即可。
注:名稱重整並不意味着一個屬性是私有的。 如果你想使一個屬性為“私人”的約定是使用一個下划線:如_parent
。 如果您知道您的類將被子類化(通常),那么使用名稱修飾以避免名稱沖突可能是一個好主意。
請參閱Python名稱修飾:如果有疑問,該怎么辦? 以決定是否使用與否,但一般而言,您應不使用它。
還要注意的是,如果子類必須能夠訪問__parent
那么你絕對 不應該使用名字改編,因為它非常的目的是為了避免子類訪問屬性。 在這種情況下,只需使用公共屬性並將其記錄下來 。 或者,您可以使用帶有名稱修飾的私有屬性和屬性/某種方法以隱藏的內部狀態訪問它,但是對於簡單的情況,這是一個過大的選擇。
__parent
是私有財產RxGUIObject
__double_leading_underscore:命名類屬性時,調用名稱修飾(在類FooBar中,__boo變為FooBar _boo;請參見下文)。
因為這是你的__parent
財產RxGUIObject
將被視為_RxGUIObject__parent
為了避免這種情況,請明確定義
def __init__(self, parent, name):
RxGUIObject.RxGUIObject.__init__(self, name, parent)
self.__body = ""
self.__javascript = ""
self.__css = ""
self.__parent = parent
self.__parent.add_child(self)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.