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

    装饰器?

    • 什么是装饰器?

    装饰器本质上是一个 Python 函数,它可以让其函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器常用场景有:插入日志、授权、计算脚本运行时间、事务处理、缓存等。

    • 加了装饰器后函数是怎么运行的?
    def new_deco(func):
        def wrapped_func(*args,**kwargs):
            print("before executing func")
            func(*args,**kwargs)
            print("after executing func")
        return wrapped
    
    
    @new_deco
    def test_func():
        print("start to executing func")
    
    
    test_func()
    print("the test_func name is:{}".format(test_func.__name__))
    
    # Outputs:
    # "before executing func"
    # "start to executing func"
    # "after executing func"
    # "the test_func name is:wrapped_func"
    

    test_func 函数的函数名被 wrapped_func。它重写了我们函数的名字和注释文档(docstring)

    from functools import wraps
    
    
    def new_deco(func):
        @wraps(func)
        def wrapped(*args,**kwargs):
            print("before executing func")
            func(*args,**kwargs)
            print("after executing func")
        return wrapped
    
    
    @new_deco
    def test_func():
        print("start to executing func")
    
    
    test_func()
    print("the test_func name is:{}".format(test_func.__name__))
    
    # Outputs:
    # "before executing func"
    # "start to executing func"
    # "after executing func"
    # "the test_func name is:test_func"
    

    @wraps 接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。

    • 不带参数装饰器的示例
    from functools import wraps
    
    def logit(func):
        @wraps(func)
        def with_logging(*args, **kwargs):
            print(func.__name__ + " was called")
            return func(*args, **kwargs)
        return with_logging
    @logit
    def addition_func(x):
       """Do some math."""
       return x + x
    
    # Output: addition_func was called
    
    • 带参数的装饰器
      • 理解:在函数中嵌入装饰器
      • 示例:
    from functools import wraps
    def logit(logfile='out.log'):
        def logging_decorator(func):
            @wraps(func)
            def wrapped_function(*args, **kwargs):
                log_string = func.__name__ + " was called"
                print(log_string)
                # 打开logfile,并写入内容
                with open(logfile, 'a') as opened_file:
                    # 现在将日志打到指定的logfile
                    opened_file.write(log_string + '
    ')
                return func(*args, **kwargs)
            return wrapped_function
        return logging_decorator
    
    @logit()
    def myfunc1():
        pass
    
    myfunc1()
    # Output: myfunc1 was called
    # 现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串
    
    @logit(logfile='func2.log')
    def myfunc2():
        pass
    
    myfunc2()
    # Output: myfunc2 was called
    # 现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串
    
    • 类装饰器
      • 概念:类装饰器具有灵活度大、高内聚、封装性等优点。可依靠内部的 call 方法
      • 示例:
    from functools import wraps
    
    
    class logit(object):
        def __init__(self, logfile='out.log'):
            self.logfile = logfile
    
        def __call__(self, func):
            @wraps(func)
            def wrapped_function(*args, **kwargs):
                log_string = func.__name__ + " was called"
                print(log_string)
                # 打开logfile并写入
                with open(self.logfile, 'a') as opened_file:
                    # 现在将日志打到指定的文件
                    opened_file.write(log_string + '
    ')
                # 现在,发送一个通知
                self.notify()
                return func(*args, **kwargs)
            return wrapped_function
    
        def notify(self):
            # logit只打日志,不做别的
            pass
    
    
    @logit()
    def myfunc1():
        print("test")
    
    
    myfunc1()
    # Output:myfunc1 was called
    #         test
    
    • 装饰器的执行顺序
    @a
    @b
    @c
    def f ():
    
    a(b(c(f)))
    

    参考资料:

    https://eastlakeside.gitbooks.io/interpy-zh/content/decorators/

    https://www.zhihu.com/question/26930016

  • 相关阅读:
    推荐几款实用的Android Studio 插件
    2015-2016最火的Android开源项目--github开源项目集锦(不看你就out了)
    [置顶] Android 2016新技术
    Android Design Support Library使用详解
    Android图片压缩(质量压缩和尺寸压缩)
    活用shape、selector和layer-list来打造自己想要的背景效果
    自定义 Material Design风格的提示框
    android:ToolBar详解
    Android 2016新技术
    文件流格式与base64格式图片上传到七牛
  • 原文地址:https://www.cnblogs.com/ronky/p/9831464.html
Copyright © 2011-2022 走看看