您好,登錄后才能下訂單哦!
裝飾器本質:就是函數,功能是為其他函數添加附加功能
裝飾器原則:
裝飾器的知識儲備:
裝飾器 = 高階函數 + 函數嵌套 + 閉包
先看一個需求:下面這個函數用來計算1到20的和
def calc(l):
res = 0
for i in l:
time.sleep(0.01)
res += i
return res
result = calc(range(1,21))
print(result)
但現在需求有變,不僅要計算1到20的和,還需要計算該函數運行的時間,此時裝飾器就應需而生
import time
def timer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
stop_time = time.time()
print('函數運行的時間為:%s' % (stop_time - start_time))
return res
return wrapper
@timer
def calc(l):
res = 0
for i in l:
time.sleep(0.01)
res += i
return res
result = calc(range(1,21))
print(result)
運行結果如下:
函數運行的時間為:0.2048475742340088
210
上面的timer函數就是calc函數的裝飾器
高階函數定義:
1.函數接收的參數是一個函數名
2.函數的返回值是一個函數名
3.滿足上述條件任意一個,都可稱之為高階函數
def foo():
print('我的函數名作為參數傳給高階函數')
def gao_jie1(func):
print('我就是高階函數1,我接收的參數名是%s' %func)
func()
def gao_jie2(func):
print('我就是高階函數2,我的返回值是%s' %func)
return func
gao_jie1(foo)
gao_jie2(foo)
#高階函數應用1:把函數當做參數傳給高階函數
import time
def foo():
print('from the foo')
def timmer(func):
start_time=time.time()
func()
stop_time=time.time()
print('函數%s 運行時間是%s' %(func,stop_time-start_time))
timmer(foo)
#總結:我們確實為函數foo增加了foo運行時間的功能,但是foo原來的執行方式是foo(),現在我們需要調用高階函數timmer(foo),改變了函數的調用方式
#高階函數應用2:把函數名當做參數傳給高階函數,高階函數直接返回函數名
import time
def foo():
print('from the foo')
def timmer(func):
start_time=time.time()
return func
stop_time=time.time()
print('函數%s 運行時間是%s' %(func,stop_time-start_time))
foo=timmer(foo)
foo()
#總結:我們確實沒有改變foo的調用方式,但是我們也沒有為foo增加任何新功能
高階函數總結
1.函數接收的參數是一個函數名
作用:在不修改函數源代碼的前提下,為函數添加新功能,
不足:會改變函數的調用方式
2.函數的返回值是一個函數名
作用:不修改函數的調用方式
不足:不能添加新功能
def father(name):
print('from father %s' %name)
def son():
print('from son')
def grandson():
print('from grandson')
grandson()
son()
father('Poe')
'''
閉包:在一個作用哉里放放定義變量,相當于打了一個包
'''
def father(name):
def son():
print('My father is %s' %name)
def grandson():
print('my grandpa is %s' %name)
grandson()
son()
father('Poe')
無參裝飾器=高級函數+函數嵌套
基本框架
'''
這就是一個實現 裝飾器最基本的架子
'''
def timer(func):
def wrapper():
func()
return wrapper()
回到上面需要計算函數運行時間的需求,在不使用裝飾器的情況下加上以下代碼
import time
def timer(func):
def wrapper():
startTime = time.time()
func()
stopTime = time.time()
print('函數運行時間為:%s' % (stopTime - startTime))
return wrapper
def test():
time.sleep(3)
print('test函數運行完畢')
res = timer(test)
res()
使用裝飾器
import time
def timer(func):
def wrapper():
startTime = time.time()
func()
stopTime = time.time()
print('函數運行時間為:%s' % (stopTime - startTime))
return wrapper
@timer #相當于test = timer(test)
def test():
time.sleep(3)
print('test函數運行完畢')
test()
返回值問題
如果test函數中有返回值怎么返回呢?test函數被調用時,實質就是調用wrapper函數,如果要返回test函數中的值,必須要在wrapper函數中將該值返回
import time
def timer(func):
def wrapper():
startTime = time.time()
res = func()
stopTime = time.time()
print('該函數運行時間為:%s' % (stopTime - startTime))
return res
return wrapper
@timer
def test():
time.sleep(1)
print('該函數運行完畢')
return '這是test的返回值'
res = test() #實質調用的是wrapper函數
print(res)
import time
def timer(func):
def wrapper(*args,**kwargs):
startTime = time.time()
res = func(*args,**kwargs)
stopTime = time.time()
print('該函數運行時間為:%s' % (stopTime - startTime))
return res
return wrapper
@timer #test = timer(test)
def test(name,age):
time.sleep(1)
print('該函數運行完畢,name is %s,age is %s' %(name,age))
return '這是test的返回值'
res = test('andy',18) #實質調用的是wrapper函數
print(res)
>>> a,b,c=(2,3,4)
>>> a
2
>>> b
3
>>> c
4
a , b, c變量要與元組中的元素一一對應才能取到值
那么再看一個實例:
>>> l=[1,2,3,4,5,6,7,8]
利用序列的方法如何取得上面列表中的第一個元素與最后一個元素
>>> l=[1,2,3,4,5,6,7,8]
>>> l
[1, 2, 3, 4, 5, 6, 7, 8]
>>> a,*_,c=l
>>> a
1
>>> c
8
>>> a,*b,c=l
>>> a
1
>>> b
[2, 3, 4, 5, 6, 7]
>>> c
8
注意:號代表除a,c變量外所有元素,號后面必須要有一個變量,使用下劃線表示*號代表的變量不想被取出
該方法可用來交換兩個變量的值:
>>> a=1
>>> b=2
>>> a,b=(b,a)
>>> a
2
>>> b
1
user_list = [
{'name':'andy','passwd':'123'},
{'name':'bruce','passwd':'123'},
{'name':'poe','passwd':'123'},
{'name':'jacky','passwd':'123'},
]
current_dic = {'username':None,'login':False}
def auth_func(func):
def wrapper(*args,**kwargs):
if current_dic['username'] and current_dic['login']:
res = func(*args,**kwargs)
return res
username = input('username:').strip()
password = input('password:').strip()
for user_dic in user_list:
if username == user_dic['name'] and password == user_dic['passwd']:
current_dic['username'] = username
current_dic['login'] = True
res = func(*args,**kwargs)
return res
else:
print('用戶名或密碼錯誤')
return wrapper
@auth_func
def index():
print('歡迎來到JD主頁' )
@auth_func
def home(name):
print('welcome %s to home' % name)
@auth_func
def shopping(name):
print('%s的購物車里有%s,%s,%s' %(name,'奶茶','妹妹','牙膏'))
print('before : ',current_dic)
index()
home('andy')
shopping('andy')
print('after: ',current_dic)
代碼執行結果:
before : {'username': None, 'login': False}
username:andy
password:123
歡迎來到JD主頁
welcome andy to home
andy的購物車里有奶茶,妹妹,牙膏
after: {'username': 'andy', 'login': True}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。