装修后如何返还值?

时间:2017-06-20 18:07:04

标签: python decorator wrapper

我使用以下脚本来评估函数test中的值是否在限制范围内:

x=[-5,5]
def test(x):
    return x

def check(min,max):
     def decorator(func):
         def wrapper(*args,**kargs):
             y=func(*args,**kargs)
             for index in range(len(y)):
                 if y[index]>max:
                     y[index]=max
                 elif y[index]<min:
                     y[index]=min
             return func(*args,**kargs)
         return wrapper
     return decorator

在此测试中,最小值为-1,最大值为1,因此我使用check(-1,1)(test(x))来装饰test(x),以便将期望的输出值设为[-1,1]。但是,输出是:

<function __main__.check.<locals>.decorator.<locals>.wrapper>

这不是预期的[-1,1]

2 个答案:

答案 0 :(得分:1)

您没有正确包装该功能。正确的句法形式是:

check(-1,1)(test)(x)

# check(-1,1)              -> returns func decorator 
#            (test)        -> returns func wrapper
#                  (x)     -> calls wrapper with one argument

最好直接在函数上使用装饰器语法:

@check(-1, -1)
def test(x):
    return x

你应该返回 y,修改后的容器,而不是在func函数中第二次调用wrapper

def wrapper(*args,**kargs):
      y = func(*args,**kargs)
      ...
      return y

答案 1 :(得分:0)

你的包装器应该返回y,这是调用未修饰函数的结果,而不是再次调用它:

x=[-5,5]

def test(x):
    return x

def check(min, max):
    def decorator(func):
        def wrapper(*args, **kargs):
            y=func(*args, **kargs)
            for index in range(len(y)):
                if y[index] > max:
                    y[index] = max
                elif y[index] < min:
                    y[index] = min
            return y  # <- change to this
        return wrapper
    return decorator

test = check(-1, 1)(test)  # decorate test function

print(test(x))  # -> [-1, 1]

如果你不想永久性地装饰test,你可以改用它:

print(check(-1, 1)(test)(x))  # -> [-1, 1]