gpt4 book ai didi

python - 为什么调用 super().foo 和 super().__getattribute__ ("foo"之间有区别)

转载 作者:行者123 更新时间:2023-12-05 03:42:08 25 4
gpt4 key购买 nike

我认为 super() 总是会尝试使用基类中的方法(或属性)运行,直到我遇到一个使用 super().__getattribute__("foo") 。简化代码如下所示。

class Base:
value = "base"

def foo(self):
print(f"Base foo, {self.value}")

class Derived(Base):
value = "derived"

def foo(self):
print(f"Derived foo, {self.value}")


def bar(self):
print(f"Derived bar {self.value}")
print(super().value)
print(super().__getattribute__("value"))
super().foo()
super().__getattribute__('foo')()

d = Derived()
d.bar()

输出,

Derived bar derived
base
derived
Base foo, derived
Derived foo, derived

有点超出我之前的理解,难道只有__getattribute__是个异常(exception)吗?我无法通过此 doc 获得更多详细信息,希望大家能帮我更清楚地理解这一点,谢谢!


编辑遵循__getattribute__问题,如下:

class Base:
value = "base"

def foo(self):
print(f"Base foo, {self.value}")


def __getattribute__(self, k):
print(f"Base get attr {self}, {k}")
return super().__getattribute__(k)


class Derived(Base):
value = "derived"

def foo(self):
print(f"Derived foo, {self.value}")


def __getattribute__(self, k):
print(f"Derived get attr {self}, {k}")
return super().__getattribute__(k)


def bar(self):
print("Derived bar")
print(super().value)
print(super().__getattribute__("value"))

d = Derived()
d.bar()

输出为:

Derived get attr <__main__.Derived object at 0x7fb0621dba90>, bar
Base get attr <__main__.Derived object at 0x7fb0621dba90>, bar
Derived bar
base
Base get attr <__main__.Derived object at 0x7fb0621dba90>, value
derived

最佳答案

super() 助手创建一个代理,它自身 修改属性访问。因此:

  • super().foosuper 代理上查找 foo
  • super().__getattribute__super 代理上查找 __getattribute__

值得注意的是,两者的结果都不知道它是通过 super 查找的:对结果的任何进一步操作都照常进行。当查找的东西是数据描述符(如方法或属性)时,它会绑定(bind)到初始的 self,而不是 super

最终,查找 super().__getattribute__ 在通常情况下只会直接或通过包装器找到标准的 object.__getattribute__ 并将其绑定(bind)到 self 。因此,调用 super().__getattribute__("foo") 等同于 object.__getattribute__(self, "foo") —— 没有 super 参与查找 .foo


比较表达式 super().foosuper().__getattribute__("foo") 的分解方式可能会有所帮助:

# super().foo
s = super()
foo = s.foo
# super().__getattribute__("foo")
s = super()
g = s.__getattribute__
foo = g("foo")

在第二种情况下,super 代理不参与查找 .foo

关于python - 为什么调用 super().foo 和 super().__getattribute__ ("foo"之间有区别),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67379274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com