首页 > 解决方案 > 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

标签: pythonoopnamespaces

解决方案


您在这里将实例与类混淆了。

方法中的self引用__init__是当前实例对象,语句self.num = ...设置该实例的属性numA.__init__()没有什么代码设置该属性的区别,因此方法和设置属性的方法之间没有区别B.__init__()

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

有一个例外;当您使用以双下划线开头(但不以双下划线结尾)的名称时,这些名称会自动重写以包含当前类作为前缀。从表达式参考文档的标识符(名称)部分

Private name mangling:当在类定义中以文本形式出现的标识符以两个或多个下划线字符开头并且不以两个或多个下划线结尾时,它被认为是该类的私有名称。在为私有名称生成代码之前,私有名称会转换为更长的形式。转换插入类名,删除前导下划线并在名称前面插入一个下划线。例如,__spam出现在名为的类中的标识符Ham将转换为_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 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

推荐阅读