zoukankan      html  css  js  c++  java
  • 装饰器

    在代码运行期间动态增加函数功能的方式,称之为装饰器(Decorator),它是一个返回函数的高阶函数
    通过decorator可以增强函数的功能,定义起来有点复杂,但使用起来非常灵活和方便

    在面向对象(OOP)的设计模式中,decorator被称为装饰模式
    OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator
    Python的decorator可以用函数实现,也可以用类实现

    使用示例

      函数的__name__属性
      函数对象都有一个__name__属性,通过该属性可获取函数名

      def now():
        print('2015-3-25')
    
      f = now
      print(now.__name__) #输出:'now'
      print(f.__name__) #输出:'now'

      使用装饰器

        def log(func):
            def wrapper(*args, **kw): 
                print('call %s():' % func.__name__)   #在wrapper()函数内,首先打印日志
                return func(*args, **kw)   #再紧接着调用原始函数
            return wrapper
            
        @log    #把@log放到now()函数的定义处,相当于执行now = log(now)
        def now():
            print('2019-5-28')   
            
        now()    #执行now()时就相当于执行log(now)
        #输出:call now():
        #       2019-5-28
        #由于log()是一个装饰器,返回的是一个函数,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数

      使用装饰器(带参数)

        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')会返回一个函数decorator,
        #然后在把now作为参数传递给函数decorator执行decorator(now),再返回wrapper并赋给now
        @log('execute')
        def now():
            print('2019-5-28')
            
        now()
        #输出:execute now():
        #       2019-5-28
        
        print(now.__name__)   #输出:wrapper
        #因为log('execute')(now)返回的是wrapper函数
        #所以需要把原始函数的__name__等属性复制到wrapper()函数中,否则有些依赖函数签名的代码执行就会出错

      通过__name__属性获取原函数名(装饰器)

        import functools
    
        def log(func):
            @functools.wraps(func)    #若要返回原函数__name__属性,直接在最后返回的函数定义上追加@functools.wraps(func)即可
            def wrapper(*args, **kw):
                print('call %s():' % func.__name__)
                return func(*args, **kw)
            return wrapper
        #Python内置的functools.wraps,专门用于实现wrapper.__name__ = func.__name__,不需要编写wrapper.__name__ = func.__name__这样的代码
        
        @log
        def now():
            print('2019-5-28')
            
        print(now.__name__)   #输出:now,因为log('execute')(now)返回的是wrapper函数

      通过__name__属性获取原函数名(带参数装饰器)

        import functools
    
        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('execute')
        def now():
            print('2019-5-28')
            
        print(now.__name__)   #输出:now,因为log('execute')(now)返回的是wrapper函数
  • 相关阅读:
    VOA 2009/11/02 DEVELOPMENT REPORT In Kenya, a Better Life Through Mobile Money
    2009.11.26教育报道在美留学生数量创历史新高
    Java中如何实现Tree的数据结构算法
    The Python Tutorial
    VOA HEALTH REPORT Debate Over New Guidelines for Breast Cancer Screening
    VOA ECONOMICS REPORT Nearly Half of US Jobs Now Held by Women
    VOA ECONOMICS REPORT Junior Achievement Marks 90 Years of Business Education
    VOA 2009/11/07 IN THE NEWS A Second Term for Karzai; US Jobless Rate at 10.2%
    Ant入门
    Python 与系统管理
  • 原文地址:https://www.cnblogs.com/shiliye/p/10937797.html
Copyright © 2011-2022 走看看