python - 父类(super class)似乎错误地引用了派生类的属性

标签 python python-3.x inheritance

在下面的 python 代码中(我使用的是 3.8),从类 A 派生的类 B 的对象调用访问父级成员的方法 barfoo通过 super() 函数调用类。因此,我希望得到与直接在 A 上调用 barfoo 相同的结果。奇怪的是,返回的内容受到 p 参数化的影响B 的情况,这不应该发生,因为 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

我已经失去了理智,所以如果有人能够阐明这种行为的基本原理并展示一种避免这种行为的方法,这将是最有帮助的。非常感谢。

最佳答案

欢迎来到super的复杂性!

super() 这里是 super(B, self) 的快捷方式。它返回一个代理,该代理将在类 MRO 中查找 B 之前的类,因此 A 和 super().bar() 会实际调用:

A.bar(self)

不改变原来的b对象...

A.bar(self)实际上是...b.p并且会给出6


如果您习惯了其他面向对象的语言,例如 C++,那么一切都会发生,就好像 Python 中的所有方法都是虚拟的(Java 措辞中的非 final方法)

关于python - 父类(super class)似乎错误地引用了派生类的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70579256/

相关文章:

python - 如何获取 Data Frame Python 中除一列以外的所有列?

python - 我如何排队我的 Python 锁?

python-3.x - 让 mypy 警告不同类型变量的相等性检查

mysql - 从请求数据中生成 XML 代码并插入到数据库中

python - 为什么 Stripe 每隔几个小时就会出现此错误 : Network error: ConnectionError:

java - 什么是更好的方法?沮丧?界面?抽象类?

python - numpy:可变大小数组 block 中值的有效求和

python - Groupby 并应用 pandas vs dask

python - 如何从基类引用 Python 派生类的 __init__ 方法?

python - 如何在 Python 的基类中创建派生类的对象?