裝飾器 萬能傳參

2022-09-06 21:18:27 字數 3831 閱讀 3226

案例

一、環境:以上為線上**,需要新增1個統計執行時間的功能。線上**如下:

1

#!/usr/bin/env python2#

-*- coding:utf8 -*-3#

author:dong ye45

import

time67

8def

test1():

9     time.sleep(3)

10print('

in the test1')

11def

test2():

12     time.sleep(3)

13print('

in the test2')

1415

16test1()

17 test2()

二、需求:在不修改源**(test1 & test2)和原**呼叫方式的情況下,給test1新增這個功能。

三、思路:

1、結合裝飾器的特點:高階函式 + 巢狀函式 =裝飾器

2、使用巢狀函式把新增功能和源**結合起來,並返回巢狀函式的記憶體位址。

3、通過高階函式把記憶體位址返回,然後重新覆蓋掉test1的函式名。

一、操作步驟:

1、先定義個高階函式的decorator。

2、巢狀函式將高階函式的記憶體位址返回給test1。

3、在高階函式中呼叫test1的函式體與新增結果結合。

例項:(以下是裝飾器的執行順序)

1

def timer(func):  #

2、timer(test1)  func = test1

2def deco():   #

3、在記憶體裡定義了乙個變數

3         start_time = time.time()  #

7、執行開始時間

4         func()                    #

8、func()執行,其實就是執行了原**test1

5         stop_time = time.time()   #

9、執行結束時間

6print('

the func run time is %s

' % (stop_time-start_time))  #

10、列印出test1的執行時間

7return deco   #

4、 返回deco函式的記憶體位址

89 test1 = timer(test1)  #

1、呼叫timer函式,將test1的變數傳給func10#

5、將deco的記憶體位址返回給test1

11 test1()   #

6、執行test1(),其實是執行了deco()函式體

1213

#test2 = timer(test2)14#

test2()

優化第乙個裝飾器**(無引數傳值):

1、由於第乙個裝飾器是按照函式呼叫傳值的方式展現的。

2、如果裝飾函式體過多則會顯得裝飾器很亂,不易讀寫。

優化後**:

1

import time #

1匯入time模組

2def timer(func): #

2相當於在記憶體中定義乙個變數 #4 @timer其實是tist1 = timer(test1),所以會呼叫到timer函式。

3def deco(): #

5、將func定義成乙個高階函式 #8 在呼叫test1時,實際呼叫的是deco函式

4         start_time = time.time() #

9 獲取當前值

5         func() #

10 呼叫源**函式

6         stop_time = time.time() #

14返回裝飾器,繼續下乙個功能

7print('

the func run time is %s

'%(stop_time-start_time)) #

15列印

8return deco #

6返回高階函式的記憶體位址

910 @timer #

這個表示test1 = timer(test1) #3指定需要裝飾的源**

11def test1(): #

11 呼叫源**

12     time.sleep(3) #

12 呼叫源**

13print('

in the test1

') #

13 呼叫源**

1415

1617 test1() #

7 呼叫test1(),實際執行的是裝飾器中的deco。

一旦這個函式被裝飾器裝飾,那麼這個函式將會被重新賦值,賦值成裝飾器函式的記憶體函式。

1

#定義巢狀函式

2def timer(func): #

定義timer函式為了傳遞test引數 func = test1

3def deco(*args,**kwargs): #

定義功能函式 #由於在工作中產的引數和引數功能不統一,所以在deco()和func()函式中使用2個萬能引數*args和**wargs;

4         start_time=time.time()

5         func(*args,**kwargs)    #

執行test傳參的函式 func() = test1()

6         stop_time =time.time()

7print('

the func run time is %s

' % (stop_time-start_time))

8return deco #

返回deco函式的記憶體位址910

11 @timer #

test1 = timer(test1) = deco test1() = deco()

12def

test1():

13     time.sleep(3)

14print('

in the test1')

1516 @timer  #

test2 = timer(test2) = deco   test2(name,age) = deco(name,age)

17def

test2(name,age):

18     time.sleep(3)

19print('

name: %s   age: %s

' %(name, age))

2021 test1() #

test1() = deco()

22 test2('

dongye

',33) #

test2(name,age) = deco(name,age)

2324

2526

#注釋:27#

test2的賦值是巢狀函式timer(test2)返回來的deco的記憶體位址;28#

在呼叫test2()的時候,實際上是在呼叫deco()函式29#

需要注意的2個地方:30#

1、呼叫test2()函式時,傳值的neme和age實際是傳值給了deco巢狀函式中;31#

2、如果deco()函式與內部執行的func()中,沒有指定形參,則會報錯;32#

3、由於在工作中產的引數和引數功能不統一,所以在deco()和func()函式中使用2個萬能引數*args和**wargs;

萬能裝飾器

萬能裝飾器 裝飾前的test 最先定義的test 是由func指向 裝飾後的test其實就是call fun 裝飾器在道德上不會去更改原先函式的返回值,不會去更改原先的引數 call fun,func,test這三個引數一般保持一致 def set fun func def call fun arg...

裝飾器的幾種形式 萬能裝飾器

1.無參無返回值 def setfunc func def print start func print end setfunc defshow print show show 在不改變原函式呼叫釋放下 新增了功能 start show end2.無參有返回值 def setfunc func de...

萬能密碼 php,PHP萬能密碼

說實話如果乙個 的前台都是注入漏洞,那麼憑經驗,萬能密碼進後台的機率基本上是百分之百。可是有的人說對php的站如果是gpc魔術轉換開啟,就會對特殊符號轉義,就徹底杜絕了php注入。其實說這話的人沒有好好想過,更沒有嘗試過用萬能密碼進php的後台。其實gpc魔術轉換是否開啟對用萬能密碼進後台一點影響也...