【发布时间】:2022-01-04 13:01:26
【问题描述】:
在下面的python代码中(我使用的是3.8),从A类派生的B类对象调用方法bar和foo通过super()函数访问父类的成员。因此,我希望得到与直接在 A 上调用 bar 和 foo 相同的结果。奇怪的是,返回的内容受 B 的 p 参数化的影响,这不应该发生,因为 A 应该屏蔽它的孩子,不应该吗?!这是要重现的代码:
class A(object):
@property
def p(self):
return 3
def bar(self):
return self.p
def foo(self):
return self.bar()
class B(A):
@property
def p(self):
return 6
def bar(self):
return super().p
def foo(self):
return super().bar()
a, b = A(), B()
print(a.p) # prints 3, OK
print(b.p) # prints 6, OK
print(a.bar()) # prints 3, OK
print(b.bar()) # prints 3, OK, since where accessing super().p
print(a.foo()) # prints 3, OK
print(b.foo()) # prints 6, NOT OK, because we are accessing super().bar() and expect 3
我在这里疯了,所以如果有人能阐明这种行为的基本原理并提出一种避免它的方法,这将是最有帮助的。非常感谢。
【问题讨论】:
-
self指的是实例,所以return self.p实际上是在说return b.p。super()只是获取 MRO 中的下一个类并将实例交给它的方法。它不会以任何方式更改实例。 -
在您的用例中使用组合而不是继承可能会更好。
-
@JReichardt 你的印象是父类不能调用派生类的方法吗?
-
作为提示:我的期望是从我从 C++ 中知道的,其中等效示例是 godbolt.org/z/4a6ao8Ybh - 我一直期望
this和self表现类似。 -
@JReichardt:Python 是一种动态语言。您期望的 C++ 行为依赖于静态类型和静态分派。 Python 不是那样工作的。
标签: python python-3.x inheritance