[英]Attributes from superclass constructor in Python 3 on created or accessible?
I am getting this traceback: 我得到此回溯:
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'
Here is a portion of the Console class: 这是Console类的一部分:
class Console(Screen.Screen):
def __init__(self):
super().__init__("REXI Console")
self.__window = Window.Window(self, 'consoleWindow')
Of the Window class: 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)
and the RxGUIObject: 和RxGUIObject:
class RxGUIObject(RxObject.RxObject):
def __init__(self, name, parent):
RxObject.RxObject.__init__(self, name)
self.__parent = parent
self.__children = list
Is Window.__parent
not created or not existent and why? Window.__parent
未创建或不存在,为什么?
You just stumbled on python's name mangling . 您刚刚偶然发现python的名称修改 。 Every attribute that starts with a double underscore and ends with at most one trailing underscore, like your
__parent
, is renamed to _ClassName__attributename
. 以双下划线开始,并在最多一个结尾下划线结束,喜欢你的每个属性
__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
Why is this done? 为什么要这样做? In order to prevent attributes clashes when subclassing.
为了防止子类化时属性冲突。 In particular the documentation states:
特别是文档指出:
Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses ), there is limited support for such a mechanism, called name mangling.
由于存在类专用成员的有效用例(即避免名称与子类定义的名称发生名称冲突 ),因此对这种称为名称修改的机制的支持有限。 Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, whereclassname
is the current class name with leading underscore(s) stripped.形式为
__spam
任何标识符(至少两个前导下划线,至多一个下划线)在文本上被_classname__spam
替换,其中classname
是当前的类名,其中前导下划线被去除。 This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.只要不存在标识符的语法位置,就可以进行这种改写,只要它出现在类的定义内即可。
Note: name mangling does not mean an attribute is private. 注:名称重整并不意味着一个属性是私有的。 If you want to make an attribute "private" the convention is to use one underscore: eg
_parent
. 如果你想使一个属性为“私人”的约定是使用一个下划线:如
_parent
。 If you know that your class will be subclassed (often), then it may be a good idea to use name mangling to avoid name clashes. 如果您知道您的类将被子类化(通常),那么使用名称修饰以避免名称冲突可能是一个好主意。
Refer to Python name mangling: When in doubt, do what? 请参阅Python名称修饰:如果有疑问,该怎么办? to decide whether to use it or not, however in general you should not use it.
以决定是否使用与否,但一般而言,您应不使用它。
Also note that, if subclasses must have access to __parent
then you definitely should not use name mangling, since its very aim is to avoid subclasses accessing the attribute. 还要注意的是,如果子类必须能够访问
__parent
那么你绝对 不应该使用名字改编,因为它非常的目的是为了避免子类访问属性。 In such cases simply use a public attribute and document it . 在这种情况下,只需使用公共属性并将其记录下来 。 In alternative you can use a private attribute with name mangling and a property/some method to access it as hidden internal state, however for simple cases this is an overkill.
或者,您可以使用带有名称修饰的私有属性和属性/某种方法以隐藏的内部状态访问它,但是对于简单的情况,这是一个过大的选择。
__parent
is private property of RxGUIObject
__parent
是私有财产RxGUIObject
__double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes FooBar _boo; see below).
__double_leading_underscore:命名类属性时,调用名称修饰(在类FooBar中,__boo变为FooBar _boo;请参见下文)。
because of this your __parent
property of RxGUIObject
will be considered as _RxGUIObject__parent
因为这是你的
__parent
财产RxGUIObject
将被视为_RxGUIObject__parent
To avoid this please define it explicetely 为了避免这种情况,请明确定义
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.