自學Python4.3-裝飾器固定格式

自學Python之路-Python基礎+模塊+面向對象
自學Python之路-Python網絡編程
自學Python之路-Python併發編程+數據庫+前端
自學Python之路-djangohtml

自學Python4.3-裝飾器固定格式

1.裝飾有返回值的裝飾器

import  time
print(time.time())

def timmer(f):    #裝飾器函數
    def inner():
        start = time.time()
        ret = f()       #被裝飾的函數
        end = time.time()
        print(end - start)
        return ret
    return inner

@timmer         #語法糖 @裝飾器函數名
def func():     #被裝飾的函數
    time.sleep(0.01)
    print('我好喜歡你們啊~')
    return '新年好'
# func = timmer(func)
ret = func()   #inner()
print(ret)  

以上代碼:
   執行timmer(func), 返回inner  (此時此刻func就是inner)  執行func的時候就是執行inner, 因此在inner裏面加個返回值前端

2. 裝飾帶參數函數的裝飾器

2.1 若是被裝飾函數有參數, 有一個參數:
數據庫

import  time
print(time.time())

def timmer(f):    #裝飾器函數
    def inner(a):
        start = time.time()
        ret = f(a)       #被裝飾的函數
        end = time.time()
        print(end - start)
        return ret
    return inner

@timmer         #語法糖 @裝飾器函數名
def func(a):     #被裝飾的函數
    time.sleep(0.01)
    print('我好喜歡你們啊',a)
    return '新年好'
# func = timmer(func)
ret = func(1)   #inner()
print(ret)

2.2  若是被裝飾函數有參數, 有2個參數:django

import  time
print(time.time())

def timmer(f):    #裝飾器函數
    def inner(a,b):
        start = time.time()
        ret = f(a,b)       #被裝飾的函數
        end = time.time()
        print(end - start)
        return ret
    return inner

@timmer         #語法糖 @裝飾器函數名
def func(a,b):     #被裝飾的函數
    time.sleep(0.01)
    print('我好喜歡你們啊',a,b)
    return '新年好'
# func = timmer(func)
ret = func(2598,2417)   #inner()
print(ret)

2.3  若是被裝飾函數有2個,一個函數有1個參數, 另外一個函數有2個參數:編程

import  time
print(time.time())

def timmer(f):    #裝飾器函數
    def inner(*args):
        start = time.time()
        ret = f(*args)       #被裝飾的函數
        end = time.time()
        print(end - start)
        return ret
    return inner

@timmer         #語法糖 @裝飾器函數名
def func1(a):     #被裝飾的函數func1
    time.sleep(0.01)
    print('我好喜歡你們啊',a)
    return '新年好'
# func = timmer(func)
def func2(a,b):     #被裝飾的函數func2
    time.sleep(0.01)
    print('我愛你們啊',a,b)
    return '過年好'
# func = timmer(func)
ret = func1(48785)   #inner()
ret = func2(2598,2417)   #inner()
print(ret)

以上只解決了按位置傳參數, 可是若是按關鍵字傳參數就會有問題。因而,  可傳萬能參數網絡

import  time
print(time.time())

def timmer(f):    #裝飾器函數
    def inner(*args,**kwargs):
        start = time.time()
        ret = f(*args,**kwargs)       #被裝飾的函數
        end = time.time()
        print(end - start)
        return ret
    return inner

@timmer         #語法糖 @裝飾器函數名
def func1(a):     #被裝飾的函數func1
    time.sleep(0.01)
    print('我好喜歡你們啊',a)
    return '新年好'
# func = timmer(func)
def func2(a,b):     #被裝飾的函數func2
    time.sleep(0.01)
    print('我愛你們啊',a,b)
    return '過年好'
# func = timmer(func)
ret = func1(48785)   #inner()
ret = func2(2598,b=2)   #inner()
print(ret)

3. 引出---裝飾器的固定格式

def wrapper(f):    #裝飾器函數,f是被裝飾的函數
    def inner(*args,**kwargs):
        '''在被裝飾函數以前要作的事'''
        ret = f(*args,**kwargs)    #被裝飾的函數
        '''在被裝飾函數以後要作的事'''
        return ret
    return inner
@wrapper         #語法糖 @裝飾器函數名
def func(a,b):     #被裝飾的函數
    time.sleep(0.01)
    print('我好喜歡你們',a,b)
    return '新年好'
ret = func()  

注意點:併發

  • func 是被裝飾的函數
  • 調用全部被裝飾的函數,其實就是調用的inner

 

 單獨打印*args,會將參數打散,輸出每個參數。(接收是聚合,調用是打散)app

因此如下的例子,inner(*args) 至關於inner(1,2,3,4) 函數

 

 舉例代碼:post

def wrapper(func):
    def inner(*args,**kwargs):
        print('在被裝飾的函數執行以前作的事')
        ret = func(*args,**kwargs)
        print('在被裝飾的函數執行以後作的事')
        return ret
    return inner

@wrapper   #holiday = wrapper(holiday)
def holiday(day):
    print('全體放假%s天'%day)
    return '好開心'

ret = holiday(3)
print(ret)

  • 1. 執行def wrapper(func) ,放到內存
  • 2. 執行holiday=wrapper(holiday)的右部分,傳給wrapper下面代碼
  • 3. 執行def inner(*args,**kwargs)
  • 4. return inner 返回地址
  • 5. 返回地址給holiday , 賦值
  • 6. 執行ret=holiday(3)右部分,  就是至關於inner(3)
  • 7. 執行inner函數,print('在被裝飾的函數執行以前作的事')
  • 8. ret = func(*args,**kwargs)  至關於holiday(*(3),**{})
  • 9. 執行函數holiday(3),print('全體放假%s天'%day)
  • 10. return 「好開心」   
  • 11. 返回值給ret = func(*args,**kwargs) 的左部分
  • 12. print('在被裝飾的函數執行以後作的事')
  • 13. return ret ,拿到返回值「好開心」
  • 14.返回值給holiday=wrapper(holiday)的左部分
  • 15.print(ret)

...

相關文章
相關標籤/搜索