• 装饰器


    装饰器是什么

    装饰器是让一个函数在执行的过程中它的前后去执行代码,在不改变原函数即原函数的调用的情况下,

    为原函数增加一些额外的功能,打印日志,执行时间,登录认证等等。

    最简单版的装饰器

    在一个函数func1执行时计算它的执行时间,此处就可以定义一个装饰器函数timer,f1 就是要测试的函数作为timer 的参数引入并执行

    import time
    装饰器函数
    def
    timer(f1): def inner(): start_time = time.time() f1() end_time = time.time() print('此函数的执行效率%s' %(end_time-start_time)) return inner
    def func1():
    print('晚上回去吃烧烤....')
    time.sleep(0.3)

    装饰被测试的函数
    func1 = timer(func1)   # func1 = inner

    @timer             #此方式相当于执行 func1 = timer(func1)
    def func1():
    print('晚上回去吃烧烤....')
        time.sleep(0.3)
    执行函数
    func1()            # inner()

    被装饰的函数带参数

    def timer(f1):                      # f1 = func1
        def inner(*args,**kwargs):     # 参数通过inner引入到f1
            start_time = time.time()
            f1(*args,**kwargs)          # func1()
            end_time = time.time()
            print('此函数的执行效率%s' %(end_time-start_time))
        return inner
    
    @timer                              # func1 = timer(func1)  inner
    def func1(a,b):
        print(a,b)
        print('这是被测试函数func1....')
        time.sleep(0.3)
    func1(111,222)                      # inner(111,222)

    接收函数的返回值

    def wrapper(f1):
        def inner(*args,**kwargs):
            '''执行函数之前的操作'''
            ret = f1(*args,**kwargs)    #通过把函数的返回值赋值给ret,最后返回即可
            '''执行函数之后的操作'''
            return ret              
        return f1
    @wrapper
    def fun1(a,b):
      return a,b               #由于func1中通过return 返回值,想要获取结果必须在inner 中赋值给ret,把值传递到最外层执行者必须return ret
    fun1(1,2)

    注意事项

    当一个函数被装饰器装饰后打印它的函数名,此时函数名已经发生了变化

    #上面的示例中已经被装饰过的函数func1再打印它的函数名字时,名字变成了装饰器的名字inner
    print
    (func1.__name__
    #output inner

    #解决  
    from functools import wraps       #引入wraps
    def timer(f1):     
    @wraps(f1)               #通过wraps装饰inner来解决此问题
    def inner(*args,**kwargs):
    start_time = time.time()
    f1(*args,**kwargs)     
    end_time = time.time()
    print('此函数的执行效率%s' %(end_time-start_time))
    return inner
    @timer                          # func1 = timer(func1)  inner
    def func1(a,b):
    print(a,b)
    print('这是被测试函数func1....')
    time.sleep(0.3)
    print(fun1.__name__)
    #output fun1

    使用场景

    授权登陆/认证

    from functools import wraps
     
    def requires_auth(f):
        @wraps(f)
        def decorated(*args, **kwargs):
            auth = request.authorization
            if not auth or not check_auth(auth.username, auth.password):    #如果未进行认证或者认证失败那么重新认证
                authenticate()  
            return f(*args, **kwargs)                         #认证通过后才真正执行操作
        return decorated

    日志功能

    from functools import wraps
     
    def logit(func):
        @wraps(func)
        def with_logging(*args, **kwargs):
            print(func.__name__ + " was called")      #执行函数func打印日志
            return func(*args, **kwargs)
        return with_logging
     
    @logit
    def addition_func(x):
       """Do some math."""
       return x + x
     
     
    result = addition_func(4)
    # 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()                            #执行logit()得到的是装饰器函数logging_decorator,所以相当于@logging_decorator
    def myfunc1():
      pass 
    myfunc1()
    # Output: myfunc1 was called
    #
    现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串


    @logit(logfile
    ='func2.log')
    def myfunc2():
      pass

    myfunc2()
    # Output: myfunc2 was called
    #
    现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串
  • 相关阅读:
    Swift入门篇-Hello World
    Swift入门篇-swift简介
    Minecraft 插件 world edit 的cs 命令
    搭建本地MAVEN NEXUS 服务
    MC java 远程调试 plugin 开发
    企业内部从零开始安装docker hadoop 提纲
    javascript 命令方式 测试例子
    ca des key crt scr
    JSF 抽象和实现例子 (函数和属性)
    form 上传 html 代码
  • 原文地址:https://www.cnblogs.com/fanggege/p/10963487.html
Copyright © 2020-2023  润新知