假设我们有三种模拟方法:
def method1(func):
def wrapper(*args, **kwargs):
#Implementation of some simulator backend
#but as a toy model we just pass a string here
return func(*args, simulation_method='method1', **kwargs)
return wrapper
def method2(func):
def wrapper(*args, **kwargs):
#Implementation of some simulator backend
#but as a toy model we just pass a string here
return func(*args, simulation_method='method2', **kwargs)
return wrapper
def method3(func):
def wrapper(*args, **kwargs):
#Implementation of some simulator backend
#but as a toy model we just pass a string here
return func(*args, simulation_method='method3', **kwargs)
return wrapper
这样我们就可以使用特定方法调用simulation
函数
@method3
def simulation(simulation_method):
#Implementation of some computation that needs to be simulated
#but as a toy model we just print the following statement:
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"
我被多重模拟的定义卡住了,很高兴能在这里得到一些帮助。谢谢!
我尝试了不同的变体,例如
def MultiSimulation(func):
def repeated_simulation(*args, **kwargs):
simulation_methods = []
if hasattr(func, '__wrapped__'):
simulation_methods = func.__wrapped__.simulation_methods
result = None
for simulation_method in simulation_methods:
kwargs['simulation_method'] = simulation_method
result = func(*args, **kwargs)
return result
repeated_simulation.simulation_methods = []
repeated_simulation.__wrapped__ = func
return repeated_simulation
但没有任何输出。
3条答案
按热度按时间4ioopgfo1#
装饰工需要返工,以保持装饰工堆叠
通过返工,您可以获得以下结果:
您需要按以下方式更新装饰器:
你需要这个装饰师:
通过对装饰器的重新设计,可以在获得不同模拟的返回值的同时使用原始样式(如果需要)。
lnlaulya2#
当你堆叠装饰器的时候,你应该注意到它们是从下往上装饰的。这意味着
method3
装饰simulation
,method2
装饰“this decored function”而不是simulation
本身。但是正如你在问题中所展示的,你需要用不同的装饰器**“repeat”**这个函数。当然有办法这样做,但我宁愿不这样做。您可以将模拟方法传递给
MultiSimulation
,如下所示:下面是一个实现:
输出:
jljoyd4f3#
我不喜欢使用任意数量的装饰器,因为在放置它们时会变得混乱和有序。这里,我将使用一个基于类的装饰器,它在构造函数中支持多个装饰器:
运行此代码将生成: