python 中基数 class 的重复数据名称
Duplicate data name from base class in python
class A:
def __init__(self):
self.num = 1
class B(A):
def __init__(self):
super().__init__()
self.num = 2
这里发生了什么,我可以在实例 A 中使用 num 数据吗?
我可以在 C++ 中执行以下操作:
n = B(); n::A.num
您在此处将实例与 class 混淆了。
__init__
方法中的self
引用是当前实例对象,语句self.num = ...
在该实例上设置属性num
。设置该属性的代码没有区别,因此设置属性的 A.__init__()
方法和 B.__init__()
方法之间没有区别。
换句话说:self.num = 2
语句最后有 运行,获胜。在 A.__init__()
中设置的值 1
被覆盖。
这有一个例外;当你使用 names that start with a double underscore (but not end with a double underscore), then those names are automatically rewritten to include the current class as a prefix. From the Identifiers (Names) section of the expression reference documentation:
Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier __spam
occurring in a class named Ham
will be transformed to _Ham__spam
.
因此,如果您使用:
class A:
def __init__(self):
self.__num = 1
class B(A):
def __init__(self):
super().__init__()
self.__num = 2
那么一个实例 b = B()
将具有两个属性,b._A__num
和 b._B__num
,它们是独立且不同的。此功能的目的是为每个 class 提供一个单独的名称空间,不会(轻易地)被 subclasses 干扰。
后者的演示:
>>> class A:
... def __init__(self):
... self.__num = 1
...
>>> class B(A):
... def __init__(self):
... super().__init__()
... self.__num = 2
...
>>> b = B()
>>> vars(b)
{'_A__num': 1, '_B__num': 2}
>>> b._A__num
1
class A:
def __init__(self):
self.num = 1
class B(A):
def __init__(self):
super().__init__()
self.num = 2
这里发生了什么,我可以在实例 A 中使用 num 数据吗?
我可以在 C++ 中执行以下操作:
n = B(); n::A.num
您在此处将实例与 class 混淆了。
__init__
方法中的self
引用是当前实例对象,语句self.num = ...
在该实例上设置属性num
。设置该属性的代码没有区别,因此设置属性的 A.__init__()
方法和 B.__init__()
方法之间没有区别。
换句话说:self.num = 2
语句最后有 运行,获胜。在 A.__init__()
中设置的值 1
被覆盖。
这有一个例外;当你使用 names that start with a double underscore (but not end with a double underscore), then those names are automatically rewritten to include the current class as a prefix. From the Identifiers (Names) section of the expression reference documentation:
Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier
__spam
occurring in a class namedHam
will be transformed to_Ham__spam
.
因此,如果您使用:
class A:
def __init__(self):
self.__num = 1
class B(A):
def __init__(self):
super().__init__()
self.__num = 2
那么一个实例 b = B()
将具有两个属性,b._A__num
和 b._B__num
,它们是独立且不同的。此功能的目的是为每个 class 提供一个单独的名称空间,不会(轻易地)被 subclasses 干扰。
后者的演示:
>>> class A:
... def __init__(self):
... self.__num = 1
...
>>> class B(A):
... def __init__(self):
... super().__init__()
... self.__num = 2
...
>>> b = B()
>>> vars(b)
{'_A__num': 1, '_B__num': 2}
>>> b._A__num
1