python-3.x 下面程序的输出显示A=30,B-30和C=30,任何人都可以解释为什么不是A=10,B=20和C=30?

zyfwsgd6  于 2023-08-08  发布在  Python
关注(0)|答案(2)|浏览(117)
class A:
    def __init__(self, x):
        self.x
    def show(self):
        print("A:", self.x)

class B(A):
    def __init__(self):
        self.x = 20

    def show(self):
        super().show()
        print("B:", self.x)

class C(B):
    def __init__(self):
        self.x = 30

    def show(self):
        super().show()
        print("C:", self.x)

obj = C()
obj.show()

字符串
尝试了代码和不同的组合,但得到的答案是A=30,B-30和C=30需要A=10,B=20和C=30。

lmyy7pcs

lmyy7pcs1#

只有一个对象(它是C的示例),所以x在每种情况下都引用相同的变量。因此,当您打印x的值时,它不可能引用基类中的单独值。
此外,正如注解中所指出的,BA__init__从未被实际调用(即使它们被调用,您也只是每次重写x的当前值,所以它总是显示相同的值)。

dwbf0jvd

dwbf0jvd2#

只有C__init__方法被调用,self.x只 * 曾经 * 设置为30。即使您确实使用了super().__init__()x的每个赋值都将覆盖之前的赋值-您仍然会得到一个值,这个值取决于super调用与super调用的顺序。分配任务对于给定的属性名称,示例只能有一个值。
如果你真的希望不同的类具有不同的值,并且假设公共接口的其余部分是正确的,那么一个工作实现应该看起来像这样:

class A:

    def __init__(self, x):
        self.__x = x

    def show(self):
        print("A:", self.__x)

class B(A):

    def __init__(self):
        super().__init__(10)
        self.__x = 20

    def show(self):
        super().show()
        print("B:", self.__x)

class C(B):

    def __init__(self):
        super().__init__()
        self.__x = 30

    def show(self):
        super().show()
        print("C:", self.__x)

字符串
使用__x作为属性名调用 name mangling(请参阅为继承设计),这意味着A实际上具有_A__xB具有_B__x,依此类推。这是故意防止子类覆盖其超类的属性--这通常不是一个好主意(例如,这不是习惯性的方法来创建“私有”属性),但是如果你 * 希望 * 每个属性都有一个单独的值,这就是你要做的。使用中:

>>> obj = C()
>>> obj.show()
A: 10
B: 20
C: 30


但是,请注意,外部访问__x也被阻止了,你必须具体说明 * 哪个 * __x

>>> obj.__x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute '__x'
>>> obj._A__x
10
>>> obj._B__x
20
>>> obj._C__x
30

相关问题