python中基类的重复数据名

python中基类的重复数据名,python,oop,namespaces,Python,Oop,Namespaces,这里发生了什么,我可以在实例A中使用num数据吗 我可以在C++中执行以下操作: n=B();n::A.num 您将实例与类混淆在一起 \uuu init\uuu方法中的self引用是当前实例对象,语句self.num=…设置该实例上的属性num。对于设置该属性的代码没有区别,因此A.\uuuuu init\uuuu()方法和设置该属性的B.\uuuuu init\uuuuu()方法之间没有区别 换句话说:self.num=2语句在最后运行后获胜。在A.\uuu init\uuuu()中设置的值

这里发生了什么,我可以在实例A中使用num数据吗

我可以在C++中执行以下操作:

n=B();n::A.num

您将实例与类混淆在一起

\uuu init\uuu
方法中的
self
引用是当前实例对象,语句
self.num=…
设置该实例上的属性
num
。对于设置该属性的代码没有区别,因此
A.\uuuuu init\uuuu()
方法和设置该属性的
B.\uuuuu init\uuuuu()方法之间没有区别

换句话说:
self.num=2
语句在最后运行后获胜。在
A.\uuu init\uuuu()
中设置的值
1
被覆盖

这是一个例外;当您使用(但不是以双下划线结尾)时,这些名称将自动重写以包含当前类作为前缀。从:

私有名称混乱:当类定义中以文本形式出现的标识符以两个或多个下划线字符开头,而不是以两个或多个下划线结尾时,它被视为该类的私有名称。在为私有名称生成代码之前,会将其转换为更长的形式。转换将在名称前面插入类名,删除前导下划线并插入一个下划线。例如,出现在名为
Ham
的类中的标识符
\uuu spam
将转换为
\uham\uu spam

因此,如果您使用:

A类:
定义初始化(自):
self.\uu num=1
B(A)类:
定义初始化(自):
super()。\uuuu init\uuuuu()
self.\uu num=2
然后一个实例
b=b()
将有两个属性,
b.\u A\u num
b.\u b\u num
,这两个属性是独立和不同的。这个特性的目的是给每个类一个独立的名称空间,它不会(很容易)被子类干扰

后者的演示:

>>A类:
...     定义初始化(自):
...         self.\uu num=1
...
>>>B(A)类:
...     定义初始化(自):
...         super()。\uuuu init\uuuuu()
...         self.\uu num=2
...
>>>b=b()
>>>vars(b)
{“数量”:1,“数量”:2}
>>>b.(数量)
1.

您正在实例上设置属性,而不是在类上设置属性。实例属性名称空间是平面的,并且没有特定于类的名称(在
\u name
约定之外,该约定显式重命名属性以使用类名作为前缀)。
class A:
    def __init__(self):
        self.num = 1

class B(A):
    def __init__(self):
        super().__init__()
        self.num = 2