1、函數屬性的傳遞 1、疊加多個裝飾器 載入順序(outter函數的調用順序):自下而上 執行順序(wrapper函數的執行順序):自上而下 2、有參裝飾器:三層的閉包函數 對於裝飾器,三層就夠了(第一層傳參數,第二層傳函數,第三層執行添加的功能和源代碼) 只能將if else這種簡單的取代,有el ...
一、裝飾器的補充
Python裝飾器(decorator)在實現的時候,被裝飾後的函數其實已經是另外一個函數了(函數名等函數屬性會發生改變),為了不影響,Python的functools包中提供了一個叫wraps的decorator來消除這樣的副作用。寫一個decorator的時候,最好在實現之前加上functools的wrap,它能保留原有函數的名稱和docstring。
簡言之:導入wraps,即可將原函數的屬性(解釋文本等)傳遞給裝飾器中對應的函數。
from functools import wraps #從 functools導入wraps
def outter(func):
1、疊加多個裝飾器
載入順序(outter函數的調用順序):自下而上
執行順序(wrapper函數的執行順序):自上而下
# 疊加多個裝飾器
# 1. 載入順序(outter函數的調用順序):自下而上
# 2. 執行順序(wrapper函數的執行順序):自上而下
def outter1(func1): #func1=wrapper2的記憶體地址
print('載入了outter1')
def wrapper1(*args,**kwargs):
print('執行了wrapper1')
res1=func1(*args,**kwargs)
return res1
return wrapper1
def outter2(func2): #func2=wrapper3的記憶體地址
print('載入了outter2')
def wrapper2(*args,**kwargs):
print('執行了wrapper2')
res2=func2(*args,**kwargs)
return res2
return wrapper2
def outter3(func3): # func3=最原始的那個index的記憶體地址
print('載入了outter3')
def wrapper3(*args,**kwargs):
print('執行了wrapper3')
res3=func3(*args,**kwargs)
return res3
return wrapper3
import time
def timmer(func):
def aaa(*args,**kwargs):
start=time.time()
res=func(*args,**kwargs)
stop=time.time()
print('run time is %s' %(stop -start))
return res
return aaa
def auth(func):
def bbb(*args,**kwargs):
name=input('name>>>: ').strip()
pwd=input('pwd>>>: ').strip()
if name == 'egon' and pwd == '123':
print('login successfull')
res=func(*args,**kwargs)
return res
else:
print('user or pwd error')
return bbb
2、有參裝飾器:三層的閉包函數
對於裝飾器,三層就夠了(第一層傳參數,第二層傳函數,第三層執行添加的功能和源代碼)
import time
from functools import wraps
current_user={'user':None}
def auth(engine='file'):
def outter(func):
二、三元表達式
只能將if else這種簡單的取代,有elif的不行。
res='ok' if False else 'no' #條件成立輸出左側的值,否則輸出右側的值,可以簡化if。。。else語句。
print(res)
輸出結果為:
no
三、生成式
列表生成式
# l=[]
# for i in range(10):
# if i>4:
# l.append(i**2)
# print(l)
上下代碼功能一致
l=[i**2 for i in range(10) if i >4] #後面不能使用else,無論是if else還是for else,可以對迴圈的參數進行操作
print(l)
輸出結果為:
[25, 36, 49, 64, 81]
# 映射和判斷
names=['egon','go_on','kevin','wxx']
print([name.upper() for name in names]) #映射關係
print([name for name in names if name.endswith('on')]) #判斷關係
print([name.upper() for name in names if name.endswith('on')]) #映射疊加判斷關係
輸出的結果:
['EGON', 'GO_ON', 'KEVIN', 'WXX']
['egon', 'go_on']
['EGON', 'GO_ON']
字典生成式:key和value需要有對應關係才好處理。
res={i:i**2 for i in range(10) if i > 3} #註意字典的生成格式
print(res)
print({i for i in 'hello'}) #註意此處生成的是集合!
輸出結果為:
{4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
{'e', 'h', 'l', 'o'}
四、匿名函數:匿名函數就是只定義了一個函數的記憶體地址,主要用於臨時使用一次的場景。
a=(lambda x,y:x+y)(1,2) #格式為“lambda 參數:表達式”後接括弧內輸入參數,匿名函數自帶return,可以得到返回值
print(a)
輸出結果為3
五、內置函數
1、max和min
print(max([10,11,-3,23])) #max會從列表中先取出兩個值比較,再將較大的和下一個值比較
輸出結果為:
23
比較value的值,然後輸出對應的key:
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
}
def func(k):
return salaries[k]
print(max(salaries,key=lambda k:salaries[k])) #此處第一個salaries是一個序列,其中的元素會被遍歷,作為參數k進行函數的運算,不理解的話看下麵
print(min(salaries,key=func)) #其實沒有必要做成有名函數,匿名函數就可以了。
# for迴圈的結果 比較依據
# 'egon' 3000
# 'alex' 100000000
# 'wupeiqi' 10000
# 'yuanhao' 2000
輸出結果為:
alex
yuanhao
max的解釋:
max(iterable, *[, key, default])
max(arg1, arg2, *args[, key])
字典是可迭代的,結果為key值,
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
}
l=list(salaries)
print(l)
輸出結果為:
['egon', 'alex', 'wupeiqi', 'yuanhao']
res=max((1,2),[1,1],key = lambda x : x[1])
print(res)
輸出結果為:
(1, 2)
sorted函數:
def sorted(*args, **kwargs): # real signature unknown
"""
Return a new list containing all items from the iterable in ascending order.
A custom key function can be supplied to customize the sort order, and the
reverse flag can be set to request the result in descending order.
"""
以升序返回包含iterable中所有項的新列表。
可以提供自定義鍵功能來自定義排序順序,以及可以設置反向標誌以按降序請求結果。
匿名函數與其他函數的結合應用:
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
}
print(sorted(salaries,key=lambda k:salaries[k],reverse=True)) #字典中的key變成序列作為參數傳入後面的匿名函數,由升序改為降序排列。
輸出結果為:
['alex', 'wupeiqi', 'egon', 'yuanhao']