小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Python進(jìn)階系列(四)

 zhulin1028 2022-06-16 發(fā)布于山東

從函數(shù)中返回函數(shù)

其實(shí)并不需要在一個(gè)函數(shù)里去執(zhí)行另一個(gè)函數(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)在試試這個(gè)

print(a())

#outputs: now you are in the greet() function

再次看看這個(gè)代碼。在if/else語句中我們返回greet和welcome,而不是greet()和welcome()。為什么那樣?這是因?yàn)楫?dāng)你把一對小括號放在后面,這個(gè)函數(shù)就會(huì)執(zhí)行;然而如果你不放括號在它后面,那它可以被到處傳遞,并且可以賦值給別的變量而不去執(zhí)行它。

你明白了嗎?讓我再稍微多解釋點(diǎn)細(xì)節(jié)。

當(dāng)我們寫下a = hi(),hi()會(huì)被執(zhí)行,而由于name參數(shù)默認(rèn)是yasoob,所以函

數(shù)greet被返回了。如果我們把語句改為a = hi(name = "ali"),那么welcome函數(shù)將被返回。我們還可以打印出hi()(),這會(huì)輸出now you are in the greet() function。

將函數(shù)作為參數(shù)傳給另一個(gè)函數(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!

現(xiàn)在你已經(jīng)具備所有必需知識,來進(jìn)一步學(xué)習(xí)裝飾器真正是什么了。裝飾器讓你在一個(gè)函數(shù)的前后去執(zhí)行代碼。

你的第一個(gè)裝飾器

在上一個(gè)例子里,其實(shí)我們已經(jīng)創(chuàng)建了一個(gè)裝飾器!現(xiàn)在我們修改下上一個(gè)裝飾器,并編寫一個(gè)稍微更有用點(diǎn)的程序:

def a_new_decorator(a_func):

??? def wrapTheFunction():

??????? print("I am doing some boring work before executing a_func()"???????

??????? a_func()???????

??????? print("I am doing some boring work after executing a_func()"

???

??? return wrapTheFunction



def a_function_requiring_decoration():

??? print("I am the function which needs some decoration to remove my foul smell")


a_function_requiring_decoration()

#outputs: "I am the function which needs some decoration to remove my foul smell


a_function_requiring_decoration=a_new_decorator(a_function_requiring_decoration)

#now a_function_requiring_decoration is wrapped by wrapTheFunction()


a_function_requiring_decoration()

#outputs:I am doing some boring work before executing a_func()

#??????? I am the function which needs some decoration to remove my foul smell

#??????? I am doing some boring work after executing a_func()

你看明白了嗎?我們剛剛應(yīng)用了之前學(xué)習(xí)到的原理。這正是python中裝飾器做的事情!它們封裝一個(gè)函數(shù),并且用這樣或者那樣的方式來修改它的行為?,F(xiàn)在你也許疑惑,我們在代碼里并沒有使用@符號?那只是一個(gè)簡短的方式來生成一個(gè)被裝飾的函數(shù)。這里是我們?nèi)绾问褂?#64;來運(yùn)行之前的代碼:


@a_new_decorator

def a_function_requiring_decoration():

??? """Hey you! Decorate me!"""

??? print("I am the function which needs some decoration to remove my foul smell")



a_function_requiring_decoration()

#outputs: I am doing some boring work before executing a_func()

#???????? I am the function which needs some decoration to remove my foul smell

#???????? I am doing some boring work after executing a_func()



#the @a_new_decorator is just a short way of saying:

a_function_requiring_decoration=a_new_decorator(a_function_requiring_decoration)

希望你現(xiàn)在對Python裝飾器的工作原理有一個(gè)基本的理解。如果我們運(yùn)行如下代碼會(huì)存在一個(gè)問題:


print(a_function_requiring_decoration.__name__)

# Output: wrapTheFunction

這并不是我們想要的!Ouput輸出應(yīng)該是“a_function_requiring_decoration”。這里的函數(shù)被warpTheFunction替代了。它重寫了我們函數(shù)的名字和注釋文檔(docstring)。幸運(yùn)的是Python提供給我們一個(gè)簡單的函數(shù)來解決這個(gè)問題,那就是functools.wraps。我們修改上一個(gè)例子來使用

functools.wraps:



from functools import wraps

def a_new_decorator(a_func):

??? @wraps(a_func)

??? def wrapTheFunction():

??????? print("I am doing some boring work before executing a_func()"

??????? a_func()

??????? print("I am doing some boring work after executing a_func()"

??? return wrapTheFunction



@a_new_decorator

def a_function_requiring_decoration():

??? """Hey yo! Decorate me!"""

??? print("I am the function which needs some decoration to remove my foul smell")



print(a_function_requiring_decoration.__name__)

# Output: a_function_requiring_decoration

現(xiàn)在好多了。我們接下來學(xué)習(xí)裝飾器的一些常用場景。

藍(lán)本規(guī)范:


from functools import wraps

def decorator_name(f):

??? @wraps(f)

??? def decorated(*args, **kwargs):

??????? if not can_run:

??????????? return "Function will not run"

??????? return f(*args, **kwargs)

??? return decorated



@decorator_name

def func():

??? return("Function is running")



can_run = True

print(func())

# Output: Function is running

can_run = False

print(func())

# Output: Function will not run

注意:@wraps接受一個(gè)函數(shù)來進(jìn)行裝飾,并加入了復(fù)制函數(shù)名稱、注釋文檔、參數(shù)列表等等的功能。這可以讓我們在裝飾器里面訪問在裝飾之前的函數(shù)的屬性。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多