python 裝飾器問題及解決方式

2022-04-02 13:07:12 字數 2936 閱讀 3757

1

#統計函式執行時間

2import

time3#

裝飾器4

deftimmer(func):

56 start_time=time.time()

7func()

8 stop_time =time.time()

9print("

the func time is %s

"%(stop_time-start_time))

1011#函式

12@timmer

13def

test1():

14 time.sleep(3)

15print('

in the test1')

1617 test1()

上面函式執行會出現報錯:

函式呼叫時出錯;

'nonetype' object is not callable

此時將呼叫函式語句去掉後面的括號,改為 test1即可。

裝飾器:本質是函式(裝飾其他函式)就是為其他函式新增附加功能 

高階函式+巢狀函式==》裝飾器

原則:不能修改被裝飾函式的原**

不能修改被裝飾函式的呼叫方式

實現裝飾器:

1.函式即『』變數『』

2.高階函式: 滿足兩個條件之一

a:把乙個函式名當做實參傳給另外乙個函式(在不修改被裝飾函式的源**的情況下,為其新增功能)。

b:返回值中包含函式名。(不修改函式的呼叫方式)

實現高階函式a

1

import

time

2def

bar():

3 time.sleep(3)

4print('

in the bar')

5#裝飾器,

6def

test1(func):

7print

(func)

8 start_time=time.time()

9 func() #

run bar

10 stop_time =time.time()

11print('

the func runtime is %s

'%(stop_time-start_time))

1213 test1(bar) #

改變了函式原本的呼叫方式

1

#裝飾器中,使用函式作為變數,通過變數也能呼叫該函式。

23 func=bar()45

func()67

#此處和bar()的執行結果是一樣的

剛開始寫裝飾器時,對函式呼叫方式有疑惑。上面**最後的語句:test(bar)改變函式原本呼叫方式很不理解。

經過斷點除錯和查閱,理解如下:

原函式沒有傳參,bar()得到的是bar這個函式的執行結果,即等待三秒後執行輸出。但是使用裝飾器後,高階函式test1(bar)函式的為原函式附加了乙個功能,即輸出函式的執行時間,但函式的呼叫變成將bar的記憶體位址賦給func,此處使用func()就是執行bar這個函式。

嚴格意義來說,上面的**並不符合裝飾器的原則。

實現高階函式b:返回值是函式名。沒有改變函式的呼叫方式。

1

import

time2#

函式的呼叫方式沒有改變

3def

bar():

4 time.sleep(3)

5print('

in the bar')

6#裝飾器7

deftest2(func):

8print

(func)

9return

func

10print('

--->

',test2(bar))#

t=test2(bar) print(t) 二者實現的效果是一樣的

11 t=test2(bar)

12 t()#

等同於bar()

1314 bar=test2(bar)

15 bar()#

等同於 run bar

上面內容:把函式bar傳給func,print(func),實質是列印下來bar的記憶體位址,return func 的返回值就是test2(bar)的執行結果。          print('--->',test2(bar))就是將test2(bar)的執行結果(即return func)的執行結果列印下來

第11行中:test2(bar())和test2(bar)的區別?

前者是將bar的執行結果傳給test2,(即字串型別),不符合高階函式中返回值是函式名這一原則。

後者將bar的記憶體位址返回給test2,之後執行。

3.函式巢狀

定義:在乙個函式體內,用def宣告乙個新的函式。(注意與函式呼叫的區別)

4.區域性作用域和全域性作用域的訪問順序

1

#區域性作用域和全域性作用域的訪問順序

2 x=0

3def

test1():

4 x=1

5print

(x)6

deftest2():

7 x=2

8print

(x)9

deftest3():

10 x=3

11print

(x)12

test3()

13test2()

14test1()

15print(x)

通過上面實現可以看出:

若將test2()注釋掉,則將不能訪問進入test3()。函式外層輸出的x的結果仍舊是0,因為它是全域性變數。

python裝飾器 Python 裝飾器

簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...

詳解Python閉包,裝飾器及類裝飾器

在專案開發中,總會遇到在原 的基礎上新增額外的功能模組,原有的 也許是很久以前所寫,為了新增新功能的 塊,您一般還得重新熟悉源 稍微搞清楚一點它的邏輯,這無疑是一件特別頭疼的事情 今天我們介紹的python裝飾器就能夠很好的解決這類問題 閉包函式 閉包比較簡單,直接上 def sum num1 1 ...

詳解Python閉包,裝飾器及類裝飾器

在專案開發中,總會遇到在原 的基礎上新增額外的功能模組,原有的 也許是很久以前所寫,為了新增新功能的 塊,您一般還得重新熟悉源 稍微搞清楚一點它的邏輯,這無疑是一件特別頭疼的事情 今天我們介紹的python裝飾器就能夠很好的解決這類問題 閉包函式 閉包比較簡單,直接上 def sum num1 1 ...