來自菜鳥教程的指導
由菜鳥教程可知這就是python的函數裝飾器,python一切皆對象
疑惑
當看到公司項目的源碼時,我這個python菜鳥對此產生了困惑,為什么def內還有def,於是上網查資料,總結了一下這個知識點,可以知道這是一個高階函數
高階函數的定義
1、函數接收的參數是一個函數名
2、函數的返回值是一個函數名
3、滿足上述要求的任意一個,就可以稱之為高階函數
def內的def
第一步,函數中定義函數
def hi(name = "hyxk"):
print("hi() function")
def greet():
return "greet() function"
def welcome():
return "welcome() function"
print(greet())
print(welcome())
print("back in the hi() function")
hi()
可以得到
#如果在函數中直接調用greet()或者welcome()會怎么樣????
def hi(name = "hyxk"):
print("hi() function")
def greet():
return "greet() function"
def welcome():
return "welcome() function"
print(greet())
print(welcome())
print("back in the hi() function")
greet()
這就會顯示greet沒有定義,但是無論在哪里都可以調用hi(),卻不能直接調用hi()內部的函數。
這就是函數內嵌套函數。
第二步,從函數中返回函數
def hi(name = "hyxk"):
def greet():
return "greet() function"
def welcome():
return "welcome() function"
if name == "hyxk":
return greet
else:
return welcome
a = hi()
print(a)
#output: <function hi.<locals>.greet at 0x0000025ED10599D8>
#可以清晰看到 a指向hi()函數中的greet()函數
print(a())
#output: greet() function
#在if/else的時候,函數返回沒有加(),如果加上(),那么就是返回函數的之,而不是返回函數了。
第三步,將函數作為參數給另一個函數
def hi():
return "hi yasoob!"
def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func())
doSomethingBeforeHi(hi)
#將hi放到func里面,將hi當成參數可以用來傳遞,在doSomethingBeforeHi函數內進行執行
第四步,修改上一個代碼變成裝飾器
def go_out(func):
def zhunbei():
print("穿衣服")
func()
print("穿褲子")
return zhunbei
def huazhuang():
print("化妝")
huazhuang = go_out(huazhuang)
#化妝這個函數由准備這個函數包裝,就相當於被go_out這個函數的內部函數裝飾
huazhuang()
#一般裝飾符就是封裝一個函數,並用這樣那樣的方法來修改他的行為
第五步,有@wraps的裝飾器
from functools import wraps
def go_out(func):
@wraps(func)
def zhunbei():
print("穿衣服")
func()
print("穿褲子")
return zhunbei
@go_out
def huazhuang():
print("化妝")
print(huazhuang.__name__)
#output:huazhuang
#其實到了這里的時候我有點暈,並不明白是什么回事,感覺這不是沒有什么裝飾效果嗎?
#但是理解一點粗淺的意思
第六步,藍本規范
from functools import wraps
def go_out(f):
@wraps(f)
def zhunbei(*args, **kwargs):
if not chuanyifu:
return "裸體出門"
return f(*args, **kwargs)
return zhunbei
@go_out
def func():
return("穿衣服出門")
chuanyifu = True
print(func())
chuanyifu = False
print(func())
#由藍本規范可以看出,func函數被go_out裝飾器裝飾,如果想執行func(),需要看func(),還需要看func()被裝飾的屬性
裝飾器還有更多的作用,后面有學到的再補充