0

私はこのトレースバックを取得しています:

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作成されていない、または存在しないのはなぜですか?

4

2 に答える 2

1

python のname manglingに出くわしました。のように、2 つのアンダースコアで始まり、最大 1 つの末尾のアンダースコアで終わるすべての属性は、__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

なぜこれが行われるのですか?サブクラス化時の属性の衝突を防ぐため。特に、ドキュメントには次のように記載されています。

class-private メンバーには有効な使用例があるため (つまり、サブクラスで定義された名前との名前の衝突を避けるため)、名前マングリングと呼ばれるそのようなメカニズムのサポートは制限されています。フォームの任意の識別子__spam(少なくとも 2 つの先頭のアンダースコア、多くても 1 つの末尾のアンダースコア) はテキストで に置き換えられます _classname__spam。ここで、classnameは先頭のアンダースコアが削除された現在のクラス名です。このマングリングは、クラスの定義内で発生する限り、識別子の構文上の位置に関係なく行われます。

注: 名前マングリングは、属性が非公開であることを意味するものではありません。属性を「非公開」にしたい場合、慣習としてアンダースコアを1 つ_parent使用します。クラスが (頻繁に) サブクラス化されることがわかっている場合は、名前の競合を避けるために名前マングリングを使用することをお勧めします。

Python の名前マングリングを参照してください。使用するかどうかを決定しますが、一般的には使用しないでください。

また、サブクラスがアクセスする必要がある場合は、名前マングリングを絶対に使用しないでください。これは、サブクラスが属性にアクセスするのを__parent避けること目的であるためです。このような場合は、単純に public 属性を使用して文書化してください。別の方法として、名前マングリングとプロパティ/メソッドを使用して非表示の内部状態としてアクセスするプライベート属性を使用できますが、単純なケースではこれはやり過ぎです。

于 2013-11-05T07:44:46.267 に答える
0

__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)
于 2013-11-05T07:45:12.503 に答える