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

如何让类的所有方法(含继承方法)被调用时执行指定逻辑?

实现子类所有方法调用时自动执行指定逻辑

我需要实现这样的逻辑:当一个子类(实际场景是list的子类)的**所有方法(包括从父类继承的方法)**被调用时,自动执行一段指定的代码。

示例需求代码如下:

class Foo(another_class):
    def __init__(self, bar):
        self.bar = bar
        super().__init__(self.bar)

    def function_to_be_called(self):
        self.bar += 1

    def function(self):
        # 执行一些操作
        pass

foo = Foo(0)
foo.function()
foo.inherited_function()
print(foo.bar)  # 期望输出2,因为function和inherited_function各被调用一次

我尝试过重写__getattribute__魔术方法,但要么触发无限递归,要么出现异常行为。


第一次尝试:触发RecursionError

class Foo(another_class):
    def __init__(self, bar):
        self.bar = bar
        super().__init__(self.bar)

    def function_to_be_called(self):
        self.bar += 1

    def function(self):
        # 执行一些操作
        pass

    def __getattribute__(self, attr):
        method = another_class.__getattribute__(self, attr)
        self.function_to_be_called()  # 调用这个方法需要通过__getattribute__查找,导致无限循环
        # 就算把self.function_to_be_called()换成直接的self.bar +=1,也会因为查找bar触发__getattribute__,同样无限递归
        return method

第二次尝试:出现异常行为(以list子类场景为例)

# 假设another_class有append方法
class Foo(another_class):
    def __init__(self, bar):
        self.bar = bar
        super().__init__(self.bar)

    def function(self):
        print(self.bar)

    def __getattribute__(self, attr):
        method = another_class.__getattribute__(self, attr)
        if callable(method):
            self.bar.sort()  # 对bar执行排序操作
        return method

foo = Foo([3, 1, 2])
print(foo)  # 实际输出[3, 1, 2],但期望是[1, 2, 3],没有执行排序
foo.append(1)
print(foo)  # 实际输出[3, 1, 2, 1],期望是[1, 1, 2, 3],还是没排序
foo.function()  # 输出[1, 2, 3],之前append的1消失了(后续测试在实际场景中又正常了,原因不明)

正确实现方案

要避免无限递归和异常行为,核心是在__getattribute__内部获取属性时,绕过当前类的__getattribute__,直接调用基类object的对应方法,同时排除不需要触发逻辑的特殊属性,避免递归。

针对计数需求的实现

class Foo(list):  # 实际场景为list的子类
    def __init__(self, bar):
        self.bar = bar
        super().__init__(self.bar)

    def function_to_be_called(self):
        # 用object.__getattribute__直接获取bar,避免触发当前__getattribute__
        current_bar = object.__getattribute__(self, 'bar')
        object.__setattr__(self, 'bar', current_bar + 1)

    def function(self):
        # 自定义方法
        pass

    def __getattribute__(self, attr):
        # 直接从object获取属性,绕过当前类的__getattribute__
        attr_value = object.__getattribute__(self, attr)
        
        # 排除function_to_be_called本身,避免递归调用
        if attr == 'function_to_be_called':
            return attr_value
        
        # 判断是否为可调用方法,包装后返回
        if callable(attr_value):
            def wrapper(*args, **kwargs):
                self.function_to_be_called()
                return attr_value(*args, **kwargs)
            return wrapper
        else:
            return attr_value

# 测试
foo = Foo(0)
foo.append(1)  # 继承自list的方法,触发计数逻辑
foo.function()  # 自定义方法,触发计数逻辑
print(foo.bar)  # 输出2,符合预期

针对排序需求的实现

class Foo(list):
    def __init__(self, bar):
        self.bar = bar.copy()  # 避免和list自身数据混淆
        super().__init__(bar)

    def __getattribute__(self, attr):
        attr_value = object.__getattribute__(self, attr)
        
        # 排除bar属性本身,避免获取bar时触发排序导致递归
        if attr == 'bar':
            return attr_value
        
        if callable(attr_value):
            def wrapper(*args, **kwargs):
                # 先执行原方法,再执行排序逻辑
                result = attr_value(*args, **kwargs)
                bar = object.__getattribute__(self, 'bar')
                bar.sort()
                return result
            return wrapper
        else:
            return attr_value

# 测试
foo = Foo([3, 1, 2])
foo.append(1)
print(foo.bar)  # 输出[1, 1, 2, 3],符合预期
foo.function()  # 输出排序后的bar

内容的提问来源于stack exchange,提问作者cd-CreepArghhh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:21:00