zoukankan      html  css  js  c++  java
  • Python3.5:装饰器的使用

    在Python里面函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数,简单来说函数也是变量也可以作文函数的参数

    >>> def funA():
    ...     print('i an funA')
    ...   time.sleep(1)
    >>> f = now
    >>> f()
    i am funA

    函数对象有一个__name__属性,可以拿到函数的名字:

    >>> funA.__name__
    'funA'
    >>> f.__name__
    'funA'

    当我们想计算这个函数的运行时间,可以再创一个函数:

    def print_time():
        start = time.time()
        funA()
        end = time.time()
        print('耗时%s秒' % (end - start))

    >>>print_time()

    i am funA
    耗时1.0043737888336182秒

    这时调用的并不是funA()而是print_time(),要是我们只能调用funA又要输出他的函数运行时间,这该怎么办?这时就可以派出今天的主人公,deractor(装饰器),简单来说在一个函数里面再嵌套一个函数,在这之前再看一个版本:

    import time
    # 随便定义一个函数
    def funA():
        print('i am funA')
        time.sleep(1)
    
    def log(func):
        def wrapper():
            start = time.time()
            func()
            end = time.time()
            print('耗时%s秒' % (end - start))
        return wrapper
    
    if __name__ == '__main__':
        n = log(funA)
        n()

    输出结果为:

    i am funA
    耗时1.0012261867523193秒

    依旧可以,但好像有点麻烦,我们可以在def funA():上面加上@log,有个小细节,log(func)必须要在funA()之前,不然@log找不到,总的代码贴上:

    import time
    # 随便定义一个函数
    def log(func):
        def wrapper():
            start = time.time()
            func()
            end = time.time()
            print('耗时%s秒' % (end - start))
        return wrapper
    @log
    def funA():
        print('i am funA')
        time.sleep(1)
    
    
    if __name__ == '__main__':
        funA()

    运行结果和上面一样,这样看起来就好多了,当然一个函数不单单可以嵌套一个函数,可以多个看你的需求,不同的嵌套发挥不同的作用。一开始说的,每个函数有个自带的.__name__属性,在主函数加个print(funA().__name__)会发现输出的是wrapper,这是因为log里面return的是wrapper,在某些情况下我们需要根据函数所属名来判断条件,那装饰器就成为累赘了,还好有个module(模块)叫functools,导入它并在def wrapper():前面加上@functools.wraps(func),意思就是将func包起来,不让他指向别的函数,这下运行结果就正常了:

    import time
    import functools
    # 随便定义一个函数
    def log(func):
        # 函数可以接受任意参数的调用
        @functools.wraps(func)
        def wrapper():
            start = time.time()
            func()
            end = time.time()
            print('耗时%s秒' % (end - start))
        return wrapper
    @log
    def funA():
        print('i am funA')
        time.sleep(1)
    
    
    if __name__ == '__main__':
        funA()
        print(funA.__name__)

    运行结果:

    i am funA
    耗时1.0033290386199951秒
    funA

  • 相关阅读:
    C# Console.Read()和Console.ReadLine()的区别
    C#获取项目程序及运行路径的方法
    Thread理解
    ENVI 监督分类Max stdev from Mean 参数IDL中的设置
    C# 插件开发学习实例
    利用动软代码器自动生存三层架构
    结构体的对齐
    链表分类及应用
    指针
    双向循环链表
  • 原文地址:https://www.cnblogs.com/doudoublog/p/7362369.html
Copyright © 2011-2022 走看看