Python 中装饰器加括号和不加括号的区别

在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())

这种装饰器就比较适合复杂的需求,例如对函数进行登录认证时,可以设置一个参数用来表示是那种认证方式等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章