裝飾器進階

一:裝飾器緩存

在不改變原函數的基礎上,額外的添加功能。app

裝飾器的返回值是一個函數對象。函數

裝飾器應用:日誌,性能測試,事務處理,緩存等場景。性能

 

 

二:裝飾器造成過程測試

一個函數的應用:計算執行時間spa

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)太麻煩了,因而有了語法糖。.net

 

不帶參數裝飾器(簡單裝飾器)日誌

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()
相關文章
相關標籤/搜索