使用装饰器时带括号与不带括号的区别

本文详细解析Python装饰器的原理及其在不同场景下的应用,包括如何使用默认和自定义装饰器,以及如何在函数调用前后进行额外操作以收集运行时信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前我们在一个用于统计函数调用消耗时间的装饰器中写了一个装饰器,用于统计函数调用时间。代码如下:

from time import time
from time import sleep

def count_time():
    def tmp(func):
        def wrapped(*args, **kargs):
            begin_time = time()
            result = func(*args, **kargs)
            end_time = time()
            cost_time = end_time - begin_time
            print '%s called cost time : %s' %(func.__name__, cost_time)
            return result
        return wrapped
    return tmp

对于该装饰器,我们必须这样使用:

@count_time()
def test():
    sleep(0.5)

if __name__ == '__main__':
    test()

这里注意,装饰器后面加了括号。

如果我们不加括号:

@count_time
def test():
    sleep(0.5)

if __name__ == '__main__':
    test()

就会产生错误:

Traceback (most recent call last):
  File "16.py", line 16, in <module>
    @count_time
TypeError: count_time() takes no arguments (1 given)

 

但是很多装饰器使用时,是不必加括号的,那么这是怎么回事?

 

我们将上面的装饰器进行改写:

from time import time
from time import sleep
import sys

def count_time(func):
    def wrapped(*args, **kargs):
        begin_time = time()
        result = func(*args, **kargs)
        end_time = time()
        cost_time = end_time - begin_time
        print '%s called cost time : %s ms' %(func.__name__, float(cost_time)*1000)
        return result
    return wrapped

此时,就不需要加括号了。

这二者的区别在于,第一个存在括号,允许用户传入自定义信息,所以需要额外包装一层,不加括号的版本则不需要。

 

所以当我们需要自定义装饰器内的某些message时,就需要采用加括号的方式。

对于这个统计时间的装饰器,我们可以这样自定义信息:

#coding: utf-8
from time import time
from time import sleep

def count_time(msg):
    def tmp(func):
        def wrapped(*args, **kargs):
            begin_time = time()
            result = func(*args, **kargs)
            end_time = time()
            cost_time = end_time - begin_time
            print 'msg: %s ,%s called cost time : %s' %(msg, func.__name__, cost_time)
            return result
        return wrapped
    return tmp

然后这样使用:

@count_time("foobar")
def test():
    sleep(0.5)

@count_time("测试消息")
def test2():
    sleep(0.7)

if __name__ == '__main__':
    test()
    test2()

结果如下:

msg: foobar ,test called cost time : 0.501540899277
msg: 测试消息 ,test2 called cost time : 0.701622009277

 

后面综合前面几篇,写一个完整的装饰器教程。

转载于:https://www.cnblogs.com/inevermore/p/4219882.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值