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

如何实现按调用顺序执行方法时排除指定父类的方法?

实现带父类排除功能的方法调用重放

现有场景

追踪已调用方法的装饰器

我们有一个装饰器,用来记录类实例中被调用过的方法:

def called_methods(func):
    def inner(self):
        func(self)
        self.called.append(func)
    return inner

三个父类定义

每个类包含两个方法,调用时会输出唯一标识语句:

class ClassOne:
    def __init__(self):
        self.called = list()

    @called_methods
    def method_one_a(self):
        print("method one, a")

    @called_methods
    def method_one_b(self):
        print("method one, b")


class ClassTwo:
    def __init__(self):
        self.called = list()

    @called_methods
    def method_two_a(self):
        print("method two, a")

    @called_methods
    def method_two_b(self):
        print("method two, b")


class ClassThree:
    def __init__(self):
        self.called = list()

    @called_methods
    def method_three_a(self):
        print("method three, a")

    @called_methods
    def method_three_b(self):
        print("method three, b")

主类实现

主类继承了上述三个父类,提供了按调用顺序重放所有已调用方法的功能:

class MainClass(ClassOne, ClassTwo, ClassThree):
    def call_functions_in_order(self):
        for function in self.called:
            function(self)

示例用法

按任意顺序调用部分方法:

test = MainClass()
test.method_one_a()
test.method_two_b()
test.method_one_b()
test.method_three_a()
test.method_two_a()
test.method_three_b()

执行后输出:

method one, a
method two, b
method one, b
method three, a
method two, a
method three, b

调用test.call_functions_in_order()会得到完全相同的输出。

需求目标

给call_functions_in_order方法添加exclude参数,指定排除某个父类的所有方法不被执行。例如调用test.call_functions_in_order(exclude='ClassOne')时,输出应为:

method two, b
method three, a
method two, a
method three, b

可行解决方案

要实现这个功能,核心是给每个记录的方法标记所属类,然后在重放时过滤掉被排除的类的方法,具体步骤如下:

1. 修改装饰器,记录方法所属类

原装饰器只存储了方法对象,我们需要额外记录该方法定义的类。可以通过方法的__qualname__属性获取类名,然后把方法和类名一起存入self.called列表:

def called_methods(func):
    def inner(self):
        func(self)
        # 拆分限定名得到类名,比如"ClassOne.method_one_a"拆分后取第一个元素
        class_name = func.__qualname__.split('.')[0]
        # 存储方法对象和对应的类名
        self.called.append((func, class_name))
    return inner

2. 修改主类方法,添加排除逻辑

更新call_functions_in_order方法,接收exclude参数,遍历记录时跳过属于排除类的方法:

class MainClass(ClassOne, ClassTwo, ClassThree):
    def call_functions_in_order(self, exclude=None):
        for function, class_name in self.called:
            # 如果没有排除类,或者当前方法不属于排除类,则执行
            if exclude is None or class_name != exclude:
                function(self)

验证效果

用之前的示例代码测试:

test = MainClass()
test.method_one_a()
test.method_two_b()
test.method_one_b()
test.method_three_a()
test.method_two_a()
test.method_three_b()

# 调用带排除参数的方法
test.call_functions_in_order(exclude='ClassOne')

输出结果完全符合需求:

method two, b
method three, a
method two, a
method three, b

扩展说明

  • 如果需要支持排除多个类,可以把exclude参数改为接收列表,比如exclude=['ClassOne', 'ClassTwo'],然后判断条件改为class_name not in exclude即可。
  • 也可以通过func.__module__或其他属性来标识类,但__qualname__是最直接获取方法所属类的方式,不受实例继承的干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:35:18