我有一个简单的函数,定义如下:
def simple_function(x):
""" x is an input numpy array"""
return x + 0.1
我想通过对它应用一些边界条件来修改此函数。这些边界条件本身就是x的函数:
def upper_bound(x):
return x**2
def lower_bound(x):
return np.zeros(len(x))
特别是,如果simple_function(x)
超过upper_bound(x)
的值,或低于lower_bound(x)
,我希望simple_function(x)
的修饰版本返回值{{1对于lower_bound,同样如此。如何在python中使用@decorator语法完成此行为?
答案 0 :(得分:2)
如果您的参数,边界和结果都是numpy数组,则可以执行几个数组赋值,以便在upper_bound
和lower_bound
函数返回的相应值之间钳制每个元素。核心部分是:
r = f(x)
l = lower_bound(x)
u = upper_bound(x)
i = r < l
j = r > u
r[i] = l
r[j] = u
i
和j
将是布尔数组,分别说明需要将哪些索引钳位到下限和上限。要使此代码作为装饰器工作,您只需将其放在一对嵌套函数中,如下所示:
def clamp(f):
@functools.wraps(f)
def wrapper(x):
r = f(x)
l = lower_bound(x)
u = upper_bound(x)
i = r < l
j = r > u
r[i] = l
r[j] = u
return r
return wrapper
functools.wraps
使包装函数复制装饰函数的名称,注释和文档字符串。
上面的代码假设您始终使用相同的upper_bound
和lower_bound
函数。如果你需要为你正在装修的不同功能定制那些,你可以添加一层额外的嵌套,并定义一个“装饰工厂”,如Ignacio Vazquez-Abrams的回答:
def clamp(lower_bound, upper_bound): # this is the decorator factory function
def decotator(f): # this is the decorator function
@functools.wraps(f)
def wrapper(x): # this is the wrapper function
... # same code here as above
return r
return wrapper
return decorator
答案 1 :(得分:0)
除了修改__doc__
等之外,你在这里:
def constrain(lower, upper):
def outer(f):
def inner(x):
r = f(x)
u = upper(x)
if r > u:
return u
l = lower(x)
if r < l:
return l
return r
return inner
return outer
...
@constrain(lower_bound, upper_bound)
def simple_function(x):
...
不处理不同的类型和低于上限的下限。