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__numb._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