閉包,裝飾器學習
高階函數
可以接受一個函數作爲參數的函數稱爲高階函數
def add(a,b):
return a+b
def behave(opt,opt_a,opt_b):
return opt(opt_a,opt_b)
print(behave(add,1,3))
閉包
在外層函數將內層函數名返回出去
閉包特點:
正常情況下,函數返回值以後,函數內局部變量所佔有的空間都會被釋放出來
但是,在閉包操作中,內層函數返回到外部時,內層函數所需的變量(包括所需要的外層函數中的變量)都會被保留出來,
調用該函數時,優先使用這一層作用域
def wrapper():
def inner():
print("hi")
return inner
man = wrapper()
man()
裝飾器
裝飾器作用
在不改變源代碼和調用方式情況下,給函數添加新功能
需要用到閉包和高階函數知識
裝飾器創建
def login(func):
def inner(*argc,**argv):
#簡單的登錄驗證程序
username = input("name>>:")
password = input("psword>>:")
if username == "xu" and password == "123":
print("歡迎登錄")
func(*argc,**argv)
else:
print("登錄失敗")
return inner
@login
def index():
print("This is homepage")
index()
1.先寫一個閉包
1)外層函數作用,就是將接受的函數參數給內層函數 def login(func):
2)內層函數經過包裝,添加一些新功能,再由外層函數將其返回 def inner(*argc,**argv):
內存函數的傳入參數,是爲了將inner所接收的參數傳入func(*argc,**argv)
被接受的參數
2.外層函數返回的是一個內層函數的函數名,這樣就導致,第一次調用外層函數時候,不會執行內層函數。
相對於login2,
func1 = login(index) #-->返回inner函數名(內層函數地址)
func1相當於inner函數,相當於
def func1(*argc,**argv): #--》相當於將inner函數指針賦值給func1
#簡單的登錄驗證程序
username = input("name>>:")
password = input("psword>>:")
if username == "xu" and password == "123":
print("歡迎登錄")
index(*argc,**argv) #---》將外層函數的參數賦值給內層函數,現在的內層函數就變成這樣
else:
print("登錄失敗")
return inner
func2 = login2(index) #-->執行login2函數,返回是None(因爲login2沒有返回值)
fun2爲none
3.將內層函數賦值給index變量
index = login(index) #--》原來index變量指向print("This is homepage")函數,現在將這個變量指向inner函數
index() #-->現在的index就相當於內層函數
以上兩步等價於
@login
def index():
print("This is homepage")
多個裝飾器
def hello(func):
def inner(*argc,**argv):
print("hello,open")
func(*argc,**argv)
return inner
@hello
@login
def index():
print("This is homepage")
index()
返回
hello,open
name>>:xu
psword>>:123
歡迎登錄
This is homepage
上面
@hello
@login
def index():
print("This is homepage")
等價於
def index():
print("This is homepage")
index = login(index)
index = hello(index)
帶參數的裝飾器
def login(auth_type):
def auth(func):
def inner(*argc,**argv):
#簡單的登錄驗證程序
username = input("name>>:")
password = input("psword>>:")
if auth_type == "qq":
print("qq登錄")
if username == "xu" and password == "123":
print("歡迎登錄")
func(*argc,**argv)
else:
print("登錄失敗")
else:
print("不支持其他登錄模式")
return inner
return auth
@login('qq')
def index1():
print("This is homepage1")
@login('weibo')
def index2():
print("This is homepage2")
print(index1())
print(index2())
結果
name>>:xu
psword>>:123
qq登錄
歡迎登錄
This is homepage1
None
name>>:xu
psword>>:123
不支持其他登錄模式
None
相當於嵌套兩次,相對於對裝飾器再增強一次,強中強