You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在子类中调用父类__getattribute__生成的自动方法?

解决子类调用父类动态生成方法的问题

你的核心问题是:父类Upgrader通过__getattribute__动态生成upgrade_vN方法,但子类Foo自己实现了同名方法后,无法在子类方法里调用父类动态生成的版本。之前尝试的几种方式失效的原因如下:

  • Upgrader.upgrade_v2(self):父类类本身没有定义upgrade_v2,动态生成逻辑是在实例的__getattribute__里,直接通过类调用找不到方法。
  • super().upgrade_v2():super()会去父类的类属性里查找方法,而父类类里没有upgrade_v2,自然找不到。
  • Upgrader.__getattribute__(self, "upgrade_v2"):这个调用会优先找实例所属类(也就是Foo)里的upgrade_v2,拿到的是子类自己的方法,不是父类动态生成的版本。

下面给出几种可行的解决方案:

方案1:改用__getattr__替代__getattribute__

__getattr__只有在实例找不到对应属性时才会触发,而__getattribute__是每次属性访问都会触发。修改父类后,可以直接调用父类的__getattr__来获取动态方法:

class Upgrader:
    max = 99

    def _upgrade_no_op(self, db):
        if self.version < Upgrader.max:
            self.version += 1

    # 把__getattribute__换成__getattr__
    def __getattr__(self, key):
        if key.startswith("upgrade_v"):
            nr = int(key[9:])
            if 0 <= nr < self.max:
                return self._upgrade_no_op
        raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{key}'")

class Foo(Upgrader):
    version = 1
    def upgrade_v2(self, db):
        # 直接调用父类的__getattr__获取动态生成的方法
        parent_upgrade = Upgrader.__getattr__(self, "upgrade_v2")
        parent_upgrade(db)
        # 这里添加子类自己的升级逻辑
        print("执行Foo自定义的v2升级逻辑")

Foo().upgrade_v2("dummy_db")

方案2:在父类中添加辅助方法

如果不想修改__getattribute__的逻辑,可以在Upgrader里加一个专门获取父类动态升级方法的函数,避免子类自己处理属性查找的细节:

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

    # 新增辅助方法,直接返回指定版本的默认升级方法
    def get_default_upgrade(self, version):
        key = f"upgrade_v{version}"
        # 跳过子类的方法,直接触发父类的动态生成逻辑
        try:
            # 先尝试从父类类属性找,找不到则走动态逻辑
            return super().__getattribute__(key)
        except AttributeError:
            if 0 <= version < self.max:
                return self._upgrade_no_op
            raise AttributeError(f"无效的升级版本:{version}")

class Foo(Upgrader):
    version = 1
    def upgrade_v2(self, db):
        # 调用辅助方法获取父类默认升级逻辑
        self.get_default_upgrade(2)(db)
        # 子类自定义逻辑
        print("执行Foo自定义的v2升级逻辑")

Foo().upgrade_v2("dummy_db")

方案3:直接调用父类的默认实现(不推荐)

如果确定父类动态生成的方法始终是_upgrade_no_op,可以直接在子类里调用这个方法,但这种方式硬编码了父类的内部实现,后续父类逻辑变更时需要同步修改子类:

class Foo(Upgrader):
    version = 1
    def upgrade_v2(self, db):
        # 直接调用父类的_no_op方法
        Upgrader._upgrade_no_op(self, db)
        # 子类自定义逻辑
        print("执行Foo自定义的v2升级逻辑")

内容的提问来源于stack exchange,提问作者Matthias Urlichs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:55:16