英文:
Output of below program show A=30, B-30 and C=30 any on can explain why not A=10, B=20 and C=30?
问题
class A:
def __init__(self, x):
self.x = x # 将 self.x 的赋值修正为 self.x = x
def show(self):
print("A:", self.x)
class B(A):
def __init__(self):
super().__init__(10) # 将 self.x 的赋值修正为 super().__init__(10)
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()
英文:
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()
Tried the code and different cobbination but got answer A=30, B-30 and C=30 Need A=10, B=20 and C=30 in mentioned.
答案1
得分: 2
只有一个对象(它是C
的一个实例),所以在每种情况下,x
都指向相同的变量。因此,当你打印x
的值时,它不可能指向基类中的不同值。
此外,如注释中所指出的,B
和A
的__init__
方法实际上从未被调用(即使被调用,也只会每次覆盖x
的当前值,因此它总是显示相同的值)。
英文:
There's only one object (which is an instance of C
), so x
refers to the same variable in each case. Thus, when you print the value of x
, it couldn't possibly refer to separate values in the base classes.
Also, as indicated in the comments, the __init__
s for B
and A
are never actually called (and even if they were, you'd just be overwriting the current value of x
every time, so it would always show the same value).
答案2
得分: 1
只有 C
的 __init__
方法被调用,self.x
只被设置为 30
。即使你使用了 super().__init__()
,对 x
的每次赋值都会覆盖任何先前的赋值 - 你仍然会得到一个值,具体取决于 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
用作属性名称会触发名称修饰(请参阅Designing for Inheritance),这意味着 A
实际上具有 _A__x
,B
具有 _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
英文:
Only C
's __init__
method gets invoked, self.x
is only ever set to 30
. Even if you did use super().__init__()
, each assignment to x
would overwrite any previous assignment - you'd still end up with one value, which one would depend on the order of the super
calls vs. assignments. An instance can only have one value for a given attribute name.
If you really do want the different classes to have different values, and assuming that the rest of the public interface is correct, a working implementation would look something like:
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)
Using __x
as the attribute name invokes name mangling (see Designing for Inheritance), which means A
actually has _A__x
, B
has _B__x
, and so on. This is deliberately intended to prevent subclasses overriding the attributes of their superclasses - it's not a good idea generally (it's not the idiomatic way to make "private" attributes, for example), but if you want each one to have a separate value this is how you do it. In use:
>>> obj = C()
>>> obj.show()
A: 10
B: 20
C: 30
However, note that external access to __x
is also prevented, you have to be specific about which __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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论