【发布时间】:2023-01-19 02:22:25
【问题描述】:
我有一个类,其方法可能会或可能不会自动生成。我希望能够从子类中调用这些方法,但不知道该怎么做。
考虑这段代码:
class Upgrader:
max = 99
def _upgrade_no_op(self, db):
if self.version < Upgrader.max:
self.version += 1
def __getattribute__(self, key):
try:
return super().__getattribute__(key)
except AttributeError:
if key.startswith("upgrade_v"):
nr = int(key[9:])
if 0 <= nr < self.max:
return self._upgrade_no_op
raise
class Foo(Upgrader):
version = 1
def upgrade_v2(self):
# None of these work:
# Upgrade.upgrade_v2(self)
# super().upgrade_v2()
# super(Foo,self).upgrade_v2()
# x = Upgrade.__getattribute__(self, "upgrade_v2"); # bound to Foo.upgrade_v2
breakpoint()
Foo().upgrade_v2()
在我的真实代码中,Foo 和Upgrader 之间还有一两个其他类,但您明白了。
有没有办法做到这一点,最好不要编写我自己的 super() 版本?
【问题讨论】:
-
只需正常调用该方法即可。
__getattribute__()方法的继承应使其适用于子类。self.upgrade_v2() -
您是否有理由像现在这样使用
__getattribute__(无条件地尝试查看它是否可以在更高级别上找到该方法)?通常,如果您希望在没有您干预的情况下发生可解析的查找,您只需使用__getattr__(仅在找不到属性时调用,就像您的try:/return super().__getattribute__(key)/except AttributeError:一样试图做)。定义__getattribute__是方法更具侵入性(每次查找都会调用它,包括简单的属性,其中super()没有意义)。 -
@Barmar:他们称之为从
upgrade_v2在子类中,所以如果他们使用self.upgrade_v2(),它就是即时无限递归;self.upgrade_v2()经过Upgrader.__getattribute__,然后得到Foo.upgrade_v2,然后调用self.upgrade_v2(),依此类推,直到它死于一堆upgrade_v2调用(__getattribute__调用可能结束堆栈,但不会在其中看到它,因为它总是在下一次真正调用Foo.upgrade_v2发生之前完全解析。 -
这看起来有点像 XY 问题。什么问题您是否试图通过支持基本上都解析为相同方法的任意命名属性来解决?
标签: python inheritance