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
1import
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:返回值是函式名。沒有改變函式的呼叫方式。
1import
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 ...