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

如何实现Python多模拟方法嵌套装饰器MultiSimulation?

实现MultiSimulation装饰器以依次执行多个模拟方法

现有三个Python装饰器method1、method2、method3,每个装饰器会为被装饰的simulation函数传入对应的模拟方法名称,实现单一模拟方法的执行。现在需要实现MultiSimulation装饰器,让被这三个装饰器修饰后的simulation函数,依次调用每个模拟方法执行,预期输出每条模拟方法的运行语句。但尝试的代码无输出,需修正实现。

现有模拟装饰器代码

def method1(func):
    def wrapper(*args, **kwargs):
        # 模拟模拟器后端实现,此处仅传入方法名字符串
        return func(*args, simulation_method='method1', **kwargs)
    return wrapper


def method2(func):
    def wrapper(*args, **kwargs):
        # 模拟模拟器后端实现,此处仅传入方法名字符串
        return func(*args, simulation_method='method2', **kwargs)
    return wrapper


def method3(func):
    def wrapper(*args, **kwargs):
        # 模拟模拟器后端实现,此处仅传入方法名字符串
        return func(*args, simulation_method='method3', **kwargs)
    return wrapper

单一模拟方法调用示例

@method3
def simulation(simulation_method):
    # 模拟需要执行的计算逻辑,此处仅打印方法信息
    print(f"Running simulation with {simulation_method} method")

# 调用后输出:Running simulation with method3 method

预期MultiSimulation使用方式

@MultiSimulation
@method1
@method2
@method3
def simulation(simulation_method):
    print(f"Running simulation with {simulation_method} method")

# 调用后预期输出:
# Running simulation with method1 method
# Running simulation with method2 method
# Running simulation with method3 method

原尝试代码的问题

原代码试图通过__wrapped__属性和自定义simulation_methods列表收集方法名,但现有模拟装饰器并未给其wrapper添加任何标记属性,导致无法收集到有效方法名,循环体未执行,因此无输出。


正确实现方案

要实现需求,我们需要让每个模拟装饰器标记自身对应的方法名,再让MultiSimulation收集这些标记并依次调用原始函数执行每个方法。

步骤1:修改现有模拟装饰器,添加方法名标记

为每个装饰器的wrapper添加方法名列表属性,用于后续收集:

def method1(func):
    def wrapper(*args, **kwargs):
        return func(*args, simulation_method='method1', **kwargs)
    # 初始化方法列表,避免覆盖已有数据
    if not hasattr(func, '_sim_methods'):
        func._sim_methods = []
    # 插入到列表头部,保证装饰顺序与执行顺序一致
    func._sim_methods.insert(0, 'method1')
    # 将属性传递给wrapper,确保多层装饰后仍能获取完整列表
    wrapper._sim_methods = func._sim_methods
    wrapper.__wrapped__ = func
    return wrapper


def method2(func):
    def wrapper(*args, **kwargs):
        return func(*args, simulation_method='method2', **kwargs)
    if not hasattr(func, '_sim_methods'):
        func._sim_methods = []
    func._sim_methods.insert(0, 'method2')
    wrapper._sim_methods = func._sim_methods
    wrapper.__wrapped__ = func
    return wrapper


def method3(func):
    def wrapper(*args, **kwargs):
        return func(*args, simulation_method='method3', **kwargs)
    if not hasattr(func, '_sim_methods'):
        func._sim_methods = []
    func._sim_methods.insert(0, 'method3')
    wrapper._sim_methods = func._sim_methods
    wrapper.__wrapped__ = func
    return wrapper

步骤2:实现MultiSimulation装饰器

从被装饰函数中获取方法名列表,遍历调用原始simulation函数:

def MultiSimulation(func):
    def repeated_simulation(*args, **kwargs):
        # 获取所有模拟方法名
        sim_methods = getattr(func, '_sim_methods', [])
        result = None
        # 找到最内层的原始simulation函数
        original_func = func
        while hasattr(original_func, '__wrapped__'):
            original_func = original_func.__wrapped__
        # 依次执行每个模拟方法
        for method in sim_methods:
            result = original_func(*args, simulation_method=method, **kwargs)
        return result
    return repeated_simulation

验证效果

使用预期方式装饰并调用:

@MultiSimulation
@method1
@method2
@method3
def simulation(simulation_method):
    print(f"Running simulation with {simulation_method} method")

simulation()

执行后输出:

Running simulation with method1 method
Running simulation with method2 method
Running simulation with method3 method

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:05:22