簡體   English   中英

來自Python 3中超類構造函數的屬性是否已創建或可訪問?

[英]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.

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