• Python装饰器--decorator


    装饰器

    装饰器实质是一个函数,其作用就是在不改动其它函数代码的情况下,增加一些功能。
    如果我们需要打印函数调用前后日志,可以这么做
    def log(func):
        print('%s is running' % func.__name__)
        func()
    
    def bar():
        print('bar')
    #将bar作为函数log参数传入
    >>>log(bar)
    bar is running
    bar

    这样写下来一个函数打印一个函数的日志是没有问题的,但是很多呢?

    def log(func)
        def wrapper(*args,**kw):
            print('%s',%func.__name__)
            return func(*args,**kw)
        return wrapper
    
    
    def bar():
        print('bar')
    
    bar
    = log(bar) bar()

    借助decorator的语法糖,一个@就可以解决

    def log(func):
        def wrapper(*args,**kw):
            print('call %s()' %func.__name__)
            return func(*args,**kw)
        return wrapper
    
    @log   #相当于bar = log(bar)
    def bar():
        print('this is bar')
    
    @log
    def bar2():
        print('this is bar2')
    装饰器在Python使用如此方便都要归因于Python的函数能像普通的对象一样能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值,可以被定义在另外一个函数内。

    装饰器是允许带参数的,装饰器的语法可以使我们在调用时,提供其他参数。

    import functools
    def log(level):
        def decorator(func):
            #@functools.wraps(func)  #这里先注释一下
            def wrapper(*args,**kw):
                print('%s %s()'% (level,func.__name__))
                return func(*args,**kw)
            return wrapper
        return decorator
    @log('execute')
    def bar():
        print('bar')
    
    >>>bar()
    execute bar()
    bar

    >>>print(bar.__name__)
    wrapper

    这里的@log('execute')相当于    bar = log('execute')(bar)

    函数对象可以通过__name__属性拿到名称

    bar.__name__  拿到的是wrapper,这是因为bar函数经过装饰器装饰之后,最终返回了wrapper函数

     

    如果不更改bar.__name__的属性,在一些依赖函数签名的代码中就会出错

    Python自带的functools.wraps就是将原始函数__name__赋值给wrapper

    import functools
    def log(level):
        def decorator(func):
            @functools.wraps(func)  #这里删除注释
            def wrapper(*args,**kw):
                print('%s %s()'% (level,func.__name__))
                return func(*args,**kw)
            return wrapper
        return decorator
    @log('execute')
    def bar():
        print('bar')
    
    >>>bar()
    execute bar()
    bar
    
    >>>print(bar.__name__)
    bar   #__name__还原成了bar

     

    类的装饰器

     

     

     

     

     

     

    参考链接知乎--Python装饰器

     

  • 相关阅读:
    内存条的物理结构分析【转载】
    JDK动态代理[2]----动态代理设计模式(文章转载于别处)
    shell 计算
    如何使用Vagrant创建linux环境(MacOS版)
    JavaFreemarker01快速上手
    7、验证信息
    6、更新文档
    5、删除文档
    4、查询文档02
    3、查询文档01
  • 原文地址:https://www.cnblogs.com/mzc1997/p/7643216.html
Copyright © 2020-2023  润新知