? ? ? ?裝飾器(Decorators)是 Python 的一個重要部分醇蝴。簡單地說:他們是修改其他函數(shù)的功能的函數(shù)。他們有助于讓我們的代碼更簡短闯参,也更Pythonic(Python范兒)峻汉。大多數(shù)初學(xué)者不知道在哪兒使用它們,所以我將要分享下播赁,哪些區(qū)域里裝飾器可以讓你的代碼更簡潔.
在函數(shù)中定義函數(shù)
剛才那些就是函數(shù)的基本知識了。我們來讓你的知識更進一步吼渡。在 Python 中我們可以在一個函數(shù)中定義另一個函數(shù):
def hi(name="yasoob"):? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????print("now you are inside the hi() function")? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?def greet():? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return "now you are in the greet() function"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?def welcome():? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????????return "now you are in the welcome() function"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????print(greet())? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????print(welcome())? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????print("now you are back in the hi() function")? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
hi()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#output:now you are inside the hi() function? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# now you are in the greet() function? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# now you are in the welcome() function? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????# now you are back in the hi() function?
# 上面展示了無論何時你調(diào)用hi(), greet()和welcome()將會同時被調(diào)用容为。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 然后greet()和welcome()函數(shù)在hi()函數(shù)之外是不能訪問的,比如:? ? ? ? ? ? ? ? ? ? ? ? ? ? greet()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????#outputs: NameError: name 'greet' is not defined
那現(xiàn)在我們知道了可以在函數(shù)中定義另外的函數(shù)寺酪。也就是說:我們可以創(chuàng)建嵌套的函數(shù)】脖常現(xiàn)在你需要再多學(xué)一點,就是函數(shù)也能返回函數(shù)寄雀。
從函數(shù)中返回函數(shù)
其實并不需要在一個函數(shù)里去執(zhí)行另一個函數(shù)得滤,我們也可以將其作為輸出返回出來:
def hi(name="yasoob"):
? ? def greet():
? ? ? ? return "now you are in the greet() function"
? ? def welcome():
? ? ? ? return "now you are in the welcome() function"
? ? if name == "yasoob":
? ? ? ? return greet? ? else:
? ? ? ? return welcome a = hi()print(a)#outputs: <function greet at 0x7f2143c01500> #上面清晰地展示了`a`現(xiàn)在指向到hi()函數(shù)中的greet()函數(shù)#現(xiàn)在試試這個 print(a())#outputs: now you are in the greet() function
再次看看這個代碼。在 if/else 語句中我們返回 greet 和 welcome咙俩,而不是 greet() 和 welcome()耿戚。為什么那樣湿故?這是因為當(dāng)你把一對小括號放在后面,這個函數(shù)就會執(zhí)行膜蛔;然而如果你不放括號在它后面坛猪,那它可以被到處傳遞,并且可以賦值給別的變量而不去執(zhí)行它皂股。
你明白了嗎墅茉?讓我再稍微多解釋點細(xì)節(jié)。
當(dāng)我們寫下a = hi()呜呐,hi() 會被執(zhí)行,而由于 name 參數(shù)默認(rèn)是 yasoob蘑辑,所以函數(shù) greet 被返回了洋魂。如果我們把語句改為a = hi(name = "ali")绷旗,那么 welcome 函數(shù)將被返回衔肢。我們還可以打印出hi()()角骤,這會輸出now you are in the greet() function。
將函數(shù)作為參數(shù)傳給另一個函數(shù)
def hi():
? ? return "hi yasoob!" def doSomethingBeforeHi(func):
? ? print("I am doing some boring work before executing hi()")? ??
????print(func()) doSomethingBeforeHi(hi)
? ?#outputs:I am doing some boring work before executing hi()
#? ? ? ? hi yasoob!