zoukankan      html  css  js  c++  java
  • 使用装饰器时带括号与不带括号的区别

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

    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

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

  • 相关阅读:
    操作系統3-內存管理(請求分頁內存管理)
    c++对象的内存模式
    操作系統3-內存管理(虛擬存儲器)
    单词统计续
    团队冲刺八
    团队冲刺七
    团队冲刺六
    团队冲刺五
    关于文件读写的各种操作
    单词统计
  • 原文地址:https://www.cnblogs.com/inevermore/p/4219882.html
Copyright © 2011-2022 走看看