python的装饰器为什么需要函数里面定义函数?

2018-12-11  本文已影响17人  飘渺的心意

对装饰器接触过的同学都知道,一般写装饰器的时候会定义一个内部的wrapper函数

def decorate(func):  # 传入函数名当然是因为python处处皆是对象
    def wrapper(a, b):
        print('*'*30)
        return func(a, b)
    return wrapper

@decorate
def add(a, b):
    return a + b

if __name__ == '__main__':
    print(add(1, 2))

输出

******************************
3

如果这么写,不去调用add函数

def decorate(func):
    print('run')
    def wrapper(a, b):
        print('*'*30)
        return func(a, b)
    return wrapper

@decorate
def add(a, b):
    return a + b

# if __name__ == '__main__':
#     print(add(1, 2))

输出

run

所以这里必须定义内部函数,这属于python的闭包

而且为什么是return wrapper而不是return wrapper()?

return wrapper可以理解为返回wrapper函数的指针

返回给add方法,在调用add方法的时候相当于执行了wrapper方法,所以wrapper也需要和add方法传入同样的参数

如果不传参:

def decorate(func):
    def wrapper():
        print('*'*30)
        return func()
    return wrapper

@decorate
def add(a, b):
    return a + b

if __name__ == '__main__':
    print(add(1, 2))

它报的错是wrapper函数需要参数

TypeError: wrapper() takes 0 positional arguments but 2 were given

而且不调用add方法的时候wrapper也不会被执行(因为返回的仅仅是指针)

如果

print(add.__name__)

输出

wrapper

当然如果想参数传递更通用,可以

def decorate(func):
    def wrapper(*args, **kwargs):
        print('*'*30)
        return func(*args, **kwargs)
    return wrapper
上一篇 下一篇

猜你喜欢

热点阅读