装饰器Decorator

作者: 布拉豆 | 来源:发表于2017-04-26 13:14 被阅读57次

    在前面的文章中知道一点,变量可以指向函数,所以变量也可以调用函数

    其实装饰器的概念,就是在执行函数外面,再套一个修饰函数,用于检查某些项是否符合。

    修饰符适用于以下场景:

    • 在用户执行某操作,操作函数一般会加上一个修饰符,来判断当前用户是否有资格执行【检查条件】
    • 代码中,对一个你不想改动的函数,记录函数的执行时间,可以用装饰器来搞定【记录日志】

    下面来举个栗子看下装饰器的使用方法:

    def log(func):
        def wrapper(*args, **kw):
            print('call %s():'% func.__name__)
            return func(*args, **kw)
        return wrapper
    
    @log
    def exec_d():
        print("exec_d")
    
    

    然后执行exec_d(),得到如下结果

    call exec_d():
    exec_d
    

    注意观察下运行结果,第一行是call exec_d():,这行的打印是在log函数中执行的;第二行exec_d是在exec_d函数中打印的

    介绍下装饰器的工作原理:

    • @log这一行代码,会被解释器翻译成log()
    • log()的括号内是放着后面行的调用函数,在这里即def exec_d():,所以最终解释成log(exec_d)

    通过变量是可以执行函数的,所以log先执行,然后在执行exec_d函数

    那如果是多个修饰符是怎么样的执行顺序呢?试一下看看....

    def log1(func):
        def wrapper(*args, **kw):
            print('call %s():'% func.__name__)
            return func(*args, **kw)
        return wrapper
    
    def log2(func):
        def wrapper(*args, **kw):
            print('call %s():'% func.__name__)
            return func(*args, **kw)
        return wrapper
    
    @log1
    @log2
    def exec_d():
        print("exec_d")
    
    exec_d()
    

    运行结果:

    call wrapper():
    call exec_d():
    exec_d
    

    运行结果这里很不妙的出现了wrapper,因为多重装饰器的执行顺序是log1(log2(exec_d)),log2作为一个函数,返回的是wrapper函数,而不是exec_d函数,这是装饰器的一个坑

    不过可以通过导入from functools import wraps,利用wraps返回func即可

    多重装饰器

    Python3教程--传送门

    相关文章

      网友评论

        本文标题:装饰器Decorator

        本文链接:https://www.haomeiwen.com/subject/iuqizttx.html