以编程方式将 "decorators" 添加到 python 函数
programmatically add "decorators" to python functions
我将装饰器放在引号中,因为根据 python 标准,它们不是严格的装饰器,尽管它们需要表现得像一个。
假设我有 3 个装饰器,f、g、h。
def f(x):
return x+1
def g(x):
return x+2
def h(x):
return x * 3
和我的 "real" fn
def orig_fn(z):
return z + 100
如何修改 orig_fn 以便在运行时链接 f,g,h 的不同组合?
如果我使用 f,g,h 中的多个,那么它们都应该被应用 - 即 orig_fn 可能 return f(g(orig_fn(x)) 。
我试过类似的方法(我真正做的是修改 class 函数 - 因此包含 MethodType)。 fn_chain 类似于 [f,g],我正在尝试一般地解决这个问题 - current_fn 是 class.
中的原始函数
if fn_chain:
print "-> creating chain"
for fn in fn_chain:
def modified_fn(self,*args,**kwargs):
return fn(self, current_fn, *args,**kwargs)
#current_fn = modified_fn
setattr(cls,f_name,types.MethodType(modified_fn,cls))
构建一个函数来组合其他函数很简单:
def compose(*funcs):
# If we compose(f, g), we want to apply g first.
funcs = funcs[::-1]
def composition(val):
for func in funcs:
val = func(val)
return val
return composition
然后你可以调用 compose(f, g, orig_fn)
来得到一个执行 f(g(orig_fn(x)))
.
的函数
我将装饰器放在引号中,因为根据 python 标准,它们不是严格的装饰器,尽管它们需要表现得像一个。
假设我有 3 个装饰器,f、g、h。
def f(x):
return x+1
def g(x):
return x+2
def h(x):
return x * 3
和我的 "real" fn
def orig_fn(z):
return z + 100
如何修改 orig_fn 以便在运行时链接 f,g,h 的不同组合?
如果我使用 f,g,h 中的多个,那么它们都应该被应用 - 即 orig_fn 可能 return f(g(orig_fn(x)) 。
我试过类似的方法(我真正做的是修改 class 函数 - 因此包含 MethodType)。 fn_chain 类似于 [f,g],我正在尝试一般地解决这个问题 - current_fn 是 class.
中的原始函数 if fn_chain:
print "-> creating chain"
for fn in fn_chain:
def modified_fn(self,*args,**kwargs):
return fn(self, current_fn, *args,**kwargs)
#current_fn = modified_fn
setattr(cls,f_name,types.MethodType(modified_fn,cls))
构建一个函数来组合其他函数很简单:
def compose(*funcs):
# If we compose(f, g), we want to apply g first.
funcs = funcs[::-1]
def composition(val):
for func in funcs:
val = func(val)
return val
return composition
然后你可以调用 compose(f, g, orig_fn)
来得到一个执行 f(g(orig_fn(x)))
.