装饰器进阶

被刻印的时光 ゝ 提交于 2020-03-01 10:13:36

一:装饰器

在不改变原函数的基础上,额外的添加功能。

装饰器的返回值是一个函数对象。

装饰器应用:日志,性能测试,事务处理,缓存等场景。

 

 

二:装饰器形成过程

一个函数的应用:计算执行时间

import time
def func1():
    print('in func1')
def timer(func):
    def inner():
            start_time=time.time()
            func()
            end_time=time.time()
            print(end_time-start_time)
    return inner
func1=timer(func1)
func1()

 

多个函数的应用时候用func1=timer(func1)太麻烦了,于是有了语法糖。

 

不带参数装饰器(简单装饰器)

import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer   #==> func1 = timer(func1)
def func1():
    print('in func1')
func1()

万能装饰器(带参数的函数)

def  wrapper(func):
    def inner(*args,**kwargs):
        ret=func(*args,**kwargs)
        return ret
    return inner
# @wrapper
# def func():
#     print()
# func()

解读:省略部分是我们要调用这个装饰器执行函数的时候用到的。

 

带参数装饰器(查看函数名和声明信息)

def  wrapper(func):
    def inner(*args,**kwargs):
        ret=func(*args,**kwargs)
        return ret
    return inner
@wrapper
def func():
    print()
func()
from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    '''哈哈哈哈'''
    print('from index')

print(index.__doc__)

 

 

带flag装饰器

def outer(flag):
    print('不用上班')
    def wrapper(func):
        print('在挺一周')
        def inner(*args,**kwargs):
            if flag:
                print('装饰器真头疼')
            ret=func(*args,**kwargs)
            if flag:
                print('我去,还不完')
            return ret
        return inner
    return wrapper
@outer(True)
def func():
    print('终于放假了')
func()

bug:@outer(True)必须放500个

改进

flag = True
def wrapper_out(flag):
    def wrapper(func):
        def inner(*args,**kwargs):
            '''执行函数前'''
            if flag:
                ret = func(*args,**kwargs)
                '''执行函数后'''
                print(222)
                return ret
            else:
                ret = func()
                return ret
        return inner
    return wrapper

@wrapper_out(flag)     #第一步是调用 wrapper_out(flag),接收到返回值wrapper
def func():           #第二步是@wrapper,即func = wrapper(func)
    print(111)
func()

 

 

 

多个装饰器装饰一个函数

def wrapper1(func):
    def inner():
        print('wrapper1 ,before func')
        func()
        print('wrapper1 ,after func')
    return inner

def wrapper2(func):
    def inner():
        print('wrapper2 ,before func')
        func()
        print('wrapper2 ,after func')
    return inner

@wrapper2
@wrapper1
def f():
    print('in f')

f()
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!