在Python 中使用装饰器的时候,可能会碰到加括号装饰和不加括号装饰器的情况。那么这两种情况到底有什么区别呢?下面分为两种情况来说明
第一种:必须不叫括号才能正常装饰的写法
import time
# 1、这种装饰不能携带括号,否则没法运行。因为@timer() 解释器在执行时会先执行 timer 函数,所以没法运行
def timer(func):
def test3(*args,**kwargs):
print('查看是否携带参数:', args, kwargs)
start_time = time.time()
x = func(*args,**kwargs)
end_time = time.time()
print('函数执行耗时:', end_time - start_time)
print('x表示被装饰函数的返回值:',x)
return x
return test3
@timer # 相当于 test1 = timer(test1),所以不能加括号,因为加括号就会被解释器 先执行timer 返回 test3,它就变成了 @tests => test1 = test3(test1),自然会报错
def test1():
time.sleep(2)
x = 1
print('in the test1')
return x
if __name__ == '__main__':
print(test1())
这种装饰器适合简单的需求,也比较好维护,容易理解。
第二种:必须要加括号才能正常装饰的写法
import time
# 2、这种情况就必须要加括号,才能正常装饰其他函数
def out_timer(name='测试'):
def timer(func):
def test3(*args,**kwargs):
print('查看是否携带参数:', args, kwargs)
start_time = time.time()
x = func(*args,**kwargs)
end_time = time.time()
print('函数执行耗时:', end_time - start_time)
print('x表示被装饰函数的返回值:',x)
return x
return test3
return timer
# 参数可以传递进去做更加复杂的操作
@out_timer() # 相当于 test2 = out_timer(test2),这个时候解释器就没法正常进行,因为out_timer是最外层装饰器,需要加括号运行out_timer 返回一个装饰器函数 timer,此时就会变为 @timer => test2 = timer(test2)
def test2():
time.sleep(1)
x = 2
print('in the test2')
return x
if __name__ == '__main__':
print(test2())
这种装饰器就比较适合复杂的需求,例如对函数进行登录认证时,可以设置一个参数用来表示是那种认证方式等。