如何实现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
相关产品推荐
相关产品推荐

