一、有參裝飾器:給裝飾器添加一個參數、來控制裝飾器的行爲。flask
@auth(參數)微信
auth裏層的函數名 = auth(參數)數據結構
被裝飾的函數名 = auth裏層的函數名(被裝飾的函數名)app
被裝飾的函數名()框架
應用場景:flask框架的路由就是有參裝飾器函數
def arg(argv):
def wrapper(func):
def inner(*args,**kwargs):
if argv:
print("開始裝飾")
ret = func(*args,**kwargs)
if argv:
print("裝飾結束")
return ret
return inner
return wrapper
def index():
print("is index")
wrapper = arg(True)
index = wrapper(index)
index()
# 結果:開始裝飾
# is index
# 裝飾結束
二、三層有參裝飾器:
msg = """
1.微信
2.抖音
3.郵箱
請選擇您要登錄的軟件:
"""
choose = input(msg)
def auth(arg):
def wrapper(func):
def inner(*args,**kwargs):
user = input("username:")
pwd = input("password:")
if arg == "1":
if user == "alex" and pwd == "alex1234":
func(*args,**kwargs)
elif arg == "2":
if user == "wusir" and pwd == "1234":
func(*args,**kwargs)
elif arg == "3":
if user == "meet" and pwd == "1234":
func(*args,**kwargs)
return inner
return wrapper
@auth(choose) #wechat = wrapper(wechat) = auth(choose)
def wechat():
print("微信")
a = auth(choose)
wechat = a(wechat)
wechat()
@auth(choose)
def dy():
print("抖音")
@auth(choose)
def email():
print("郵箱")
if choose == "1":
wechat()
elif choose == "2":
dy()
elif choose == "3":
email()
結果:微信
三、有參裝飾器微信、抖音、郵箱:
msg = """
微信
抖音
郵箱
請選擇您要登錄的軟件:
"""
choose = input(msg)
def auth(arg):
def wrapper(func):
def inner(*args,**kwargs):
user = input("username:")
pwd = input("password:")
if arg == "微信":
if user == "alex" and pwd == "alex1234":
func(*args,**kwargs)
else:
print("帳號或密碼錯誤!")
elif arg == "抖音":
if user == "wusir" and pwd == "1234":
func(*args,**kwargs)
else:
print("帳號或密碼錯誤!")
elif arg == "郵箱":
if user == "meet" and pwd == "1234":
func(*args,**kwargs)
else:
print("帳號或密碼錯誤!")
return inner
return wrapper
@auth(choose) #wechat = wrapper(wechat) = auth(choose)
def wechat():
print("微信")
@auth(choose)
def dy():
print("抖音")
@auth(choose)
def email():
print("郵箱")
func_dic = {
"微信":wechat,
"抖音":dy,
"郵箱":email
}
if choose in func_dic:
func_dic[choose]()
else:
print("輸入有誤請從新輸入!")
四、多個裝飾器裝飾一個函數時先執行離被裝飾的函數最近的裝飾器:
def f1(func): #func == index
def f2(*args,**kwargs):
print("這是f1的裝飾開始")
func(*args,**kwargs)
print("這是f1的裝飾結束")
return f2
def foo1(func): #func == f2
def foo2(*args,**kwargs):
print("這是foo1的裝飾開始")
func(*args,**kwargs)
print("這是foo1的裝飾結束")
return foo2
@foo1 #index = foo1(index) #index = foo1(f2)
@f1 #index = f1(index) #如今的index其實就是返回的f2
def index():
print("is index")
index() #foo2()
結果: 這是foo1的裝飾開始
這是f1的裝飾開始
is index
這是f1的裝飾結束
這是foo1的裝飾結束測試
看到的真不爲真spa
看到的真不爲真3d
看到的真不爲真對象
五、遞歸的精華:一遞一歸。
六、遞歸的定義:不斷調用本身自己(死遞歸)
有明確的結束條件
七、死遞歸以下:
def func():
print(1)
func()
func()
結果:RecursionError: maximum recursion depth exceeded while calling a Python object--遞歸錯誤:調用Python對象時,最大遞歸深度超過了
最大深度/層次、官方:1000、實際測試:998/997
八、修改遞歸最大深度:
import sys
sys.setrecursionlimit(1000)
九、遞歸舉例:
def age(n):
if n == 3:
return 18
def age1(n):
if n == 3:
return 18
return age(n + 1) - 2
def age2(n):
if n == 3:
return 18
return age1(n + 1) - 2
print(age2(1))
# 結果:14
十、階乘5層 1,2,3,4,5
結果:120
十一、斐波那契數列:1,1,2,3,5,8,13,21,34,55
十二、遞歸效率低:每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減小,遞歸效率不高,遞歸層次過多會致使棧溢出(在計算機中,函數調用就是經過棧(stack)這種數據結構實現的,每當進入一個函數調用時,棧就會增長一層棧,每當函數返回時,棧就會減小一層,因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出。
做業題: