• python3(十八)decorator


    # -----------------------1--------------------------------------------
    # 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。
    def now():
        print('2019-3-25')
    
    
    f = now
    print(f())  # 2019-3-25
    print(now.__name__)  # now
    print(f.__name__)  # now
    
    
    # ----------------------2---------------------------------------------
    # 增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,
    # 这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
    def log(func):
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)
    
        return wrapper
    
    
    # 上面的log,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。
    # 我们要借助Python的@语法,把decorator置于函数的定义处
    @log
    def now():
        print('2019-3-26')
    
    
    now()  # call now():  2019-3-26
    
    
    # print(now.__name__) # wrapper
    
    # 把@log放到now()函数的定义处,相当于 now = log(now)
    # 由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。
    # wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。
    
    # ----------------3----------------------------------------------------
    # 自定义log的文本:
    def log(text):
        def decorator(func):
            def wrapper(*args, **kw):
                print('%s %s():' % (text, func.__name__))
                return func(*args, **kw)
    
            return wrapper
    
        return decorator
    
    
    # 如下@ 相当于now = log('execute')(now)
    @log('execute')
    def now():
        print('2015-3-27')
    
    
    now()  # execute now(): 2015-3-27
    # 上面的语句,首先执行log('execute'),返回的是decorator函数,
    # 再调用返回的函数,参数是now函数,返回值最终是wrapper函数。
    
    # ----------------------4----------------------------------------------
    print(now.__name__)  # wrapper
    # 因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的__name__等属性复制到wrapper()函数中,
    # 否则,有些依赖函数签名的代码执行就会出错。
    # 不需要编写wrapper.__name__ = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的
    # 修改log
    import functools
    
    
    def log(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)
    
        return wrapper
    
    
    #
    # def log(text):
    #     def decorator(func):
    #         @functools.wraps(func)
    #         def wrapper(*args, **kw):
    #             print('%s %s():' % (text, func.__name__))
    #             return func(*args, **kw)
    #         return wrapper
    #     return decorator
    
    @log
    def now():
        print('2019-3-28')
    
    
    print(now.__name__)  # now
  • 相关阅读:
    装饰器模式
    mockups 安装
    单例设计模式
    css优先级问题
    GPU的nvadiasmi解析
    conda配置镜像并安装gpu版本pytorch和tensorflow2
    索引的优化
    [转]必须掌握的八个【cmd 命令行】
    BDE莫名的不自动COMMIT问题
    窗体控件笔记
  • 原文地址:https://www.cnblogs.com/shaozhiqi/p/11543658.html
Copyright © 2020-2023  润新知