裝飾器(函式)
裝飾器作為乙個函式,可以為其他函式在不修改原函式**的前提下新增新的功能
裝飾器的返回值是乙個函式物件。它經常用於有切面需求的場景,比如:插入日誌、效能測試、事務處理、快取、許可權校驗等。
裝飾器,可以讓我們抽離出大量與函式功能本身無關的相同**並在裝飾器函式中使用
裝飾器的三個重要要素:
一、作用域
二、高階函式
三、閉包
一、作用域
l.local,區域性作用域;e.enclosing,巢狀作用域;g.global,全域性作用域;b.built-in,內建作用域
作用域的優先搜尋順序:區域性作用域》外層巢狀作用域》當前模組(巢狀函式中)的全域性作用域》python內建作用域;
二、高階函式
把函式作為引數傳入,即函式本身也可以作為乙個變數,這樣的函式稱為高階函式
高階函式,就是為了讓函式的引數能夠接收到別的函式
三、閉包
閉包函式可以脫離函式,在函式的外部單獨地進行呼叫
閉包 = 內部函式 + 定義函式時的環境
閉包的兩個條件:1、擁有內部函式;2、對外部環境的乙個變數進行引用
def outer():
x = 'hello world!' #定義函式的變數(環境)
def inner(): #條件1,,inner是內部函式
print(x) #條件2,對外部環境的乙個變數進行引用
return inner #結論,內部函式inner就是乙個閉包
f = outer()
f()>>> hello world!
裝飾器eg1.計算總用時的裝飾器
import time
def show_time(f):
def inner():
start = time.time()
f()end = time.time()
res = end - start
print('總用時:',res)
return inner
@show_time #效果相當於 func1=show_time(func1)
def func1():
print('-----------功能1-----------')
time.sleep(2) # 延時2s
@show_time #效果相當於 func2=show_time(func2)
def func2():
print('-----------功能2-----------')
time.sleep(3) # 延時3s
func1()
func2()
>>>-----------功能1-----------
總用時: 2.0070815086364746
-----------功能2-----------
總用時: 3.0007598400115967
eg2.帶引數的裝飾器(如果被裝飾的函式中有引數,則裝飾器函式中也要帶上引數)
import time
def show_time(f):
def inner(*args,**kwargs):
start = time.time()
f(*args,**kwargs)
end = time.time()
res = end - start
print('總用時:',res)
return inner
@show_time #效果相當於 func1=show_time(func1)
def func3(*args,**kwargs):
sums = 0
for i in args:
sums += i
print('-----------加法器-----------')
print('結果是:',sums)
func3(5,6,1,4)
>>>-----------加法器-----------
結果是: 16
總用時: 0.0
eg3.帶引數的裝飾器(引數為設定的條件,判斷是否需要執行修飾器)
import time
def flag(flag = 'false'):
def show_time(f):
def inner(*args,**kwargs):
if flag == 'true':
start = time.time()
f(*args,**kwargs)
end = time.time()
print('time: %s'%(end-start))
else:
f(*args, **kwargs)
return inner
return show_time
@flag('true') # flag = 'true',執行總用時裝飾器
def add(*args,**kwargs):
sum = 0
for i in args:
sum+=i
print('-----add的執行結果-----')
print(sum)
time.sleep(1)
@flag('false') # flag = 'false',不執行總用時裝飾器
def add1(*args,**kwargs):
sum = 0
for i in args:
sum+=i
print('-----add1的執行結果-----')
print(sum)
time.sleep(1)
add(1,4)
add1(1,4)
>>> -----add的執行結果-----
time: 1.0008649826049805
-----add1的執行結果-----
注意:我們在呼叫裝飾器時,提供了其它引數,@flag()預設的引數為false,則不會輸出總用時裝飾器;
當@flag()引數為true時,輸出總用時。這樣是在原有的裝飾器上加了一層判斷;
當我們使用@flag(『true』)呼叫的時候,python能夠發現這一層的封裝,並把引數傳遞到裝飾器的環境中;
python學習 裝飾器
def w1 func def inner print 正在驗證 func 閉包 return inner def f1 print f1 def f2 print f2 f1 w1 f1 呼叫的 f1 發生改變 f1 在沒有修改 f1 引用的前提下,完成對 f1 的擴充套件 執行結果 在很多情況下...
python裝飾器學習
1 裝飾器的本質 閉包函式 2 裝飾器的作用 在不改變原函式的呼叫方式情況下,給原函式增加其他功能。3 開發原則 開放封閉原則。4 語法 裝飾器函式名 閉包函式 巢狀函式,內部函式呼叫外部函式的變數。def outer arg1 def inner print arg1 return inner i...
python學習(裝飾器)
裝飾器就是閉包的具體使用,可以不改變原來的函式 對其功能進行擴充。import time def outer func def inner num t1 time.time func num t2 time.time print 時間為 t2 t1 return inner outer def fu...