適合初學者的Python裝飾器簡易教程

2021-10-05 23:43:46 字數 2976 閱讀 4365

裝飾器是python程式語言中相當高階的一部分。

就像大多數事情一樣,一旦你掌握了它們的工作原理並使用了幾次,它們就會變得非常簡單明瞭,但是作為乙個初學者,它們可能會有點讓人望而生畏,很難理解。只有理解了它所解決的問題,你才能真正理解它。

例如,我可以直接宣告裝飾器的定義:

decorator是乙個函式,它將另乙個函式作為引數並返回它的修改版本,以某種方式增強了它的功能。

如果您已經了解了decorator是什麼,那麼這個定義就非常清楚了,但是如果您不了解,那麼可能就不太了解了。重要的是,這個定義本身並不能告訴您什麼時候使用修飾符,或者沒有修飾符python會變得多麼糟糕。

舉例

我們將從乙個假設的場景開始,並觀察如果不使用decorator可能出現的問題。在你上班的第一天,你的老闆找到你,讓你寫乙個函式,這個函式將乙個字串轉換成乙個回文:乙個向前和向後讀取相同內容的字串。

你可以這樣寫:

def make_palindrome(string):

"""makes a palindromic mirror of a string."""

return string + string[::-1]

到目前為止一切順利。一小時後,老闆要求更多的函式:乙個credits函式在任何字串的末尾新增乙個字串,乙個函式將字串轉換到另乙個字串中,還有乙個函式在字串中插入逗號。

你開始加入新的函式:

def add_credits(string):

"""adds the company's credits to the end of any string."""

return f" (string created by pro string inc.)"

​def snake_to_camel(string):

"""converts a string in snake_case to camelcase."""

words = string.split("_")

if len(words) > 1:

words = [words[0]] + [word.title() for word in words[1:]]

return "".join(words)

def insert_commas(string, spacing=3):

"""inserts commas between every n characters."""

sections = [string[i: i + spacing] for i in range(0, len(string), spacing)]

return ",".join(sections)

if isinstance(string, int):    string = str(string)
當我們有四個需要修改的函式時,這是可以的,但是如果我們有十個呢?讓所有的功能都以相同的兩行開始違背了神聖的「不要重複自己」的法律準則。

難道沒有一種方法可以只修改所有這些函式而不新增額外**嗎?

要了解如何做到這一點,讓我們回過頭來看看python函式。儘管python函式有特殊的語法,但它只是乙個物件,就像字串或列表一樣。您可以檢查它們的屬性,將它們分配給新的變數,並且——至關重要的是——將它們作為引數傳遞給另乙個函式。

例如,您可以使乙個函式接受另乙個函式,並檢查它是否有任何關鍵字引數:

def func_has_kwargs(func):    

return len(func.__defaults__) > 0

不要擔心__defaults__如果你還沒見過,這裡的關鍵是,函式是另乙個函式作為引數,檢查是否有任何關鍵字引數(即如果__default__產權的長度大於0)。否則,返回true,如果是這樣,則返回false。

現在回到我們的問題之中。我們有三個精心設計的字串操作函式,我們需要修改它們,使它們也接受整數。我們需要的是乙個新函式——它將把我們現有的函式作為輸入,並建立乙個修改後的函式來檢查整數。

我們需要乙個裝飾函式:

讓我們仔細看看這裡發生了什麼。accept_integers是我們的裝飾函式——它接受乙個函式作為輸入,返回另乙個函式作為輸出。在它的主體中,它建立了乙個新函式,該函式應該完成輸入函式所做的所有事情,但是在開始時需要乙個額外的步驟。

如果您檢視這個函式的主體,您可以看到它檢查給定的字串是否為整數,如果是整數則轉換它,然後將這個字串傳遞給原始函式。這裡缺少乙個步驟——我們需要實際使用這個裝飾器:

標準形式

最後,值得指出的是,雖然上面的語法是完全有效的,但是python以@符號的形式提供了快捷方式。可以將@accept_integers新增到任何函式的前面來修飾它:

這是將乙個函式傳遞給另乙個函式的另一種方式。在底層,當python看到@符號時,它會為您執行decorator的呼叫。許多python庫都提供裝飾器,以快速增強編寫的函式,而不必輸入大量重複的**。

我們對裝飾師和所有新程式設計特性的建議是,首先要學會識別使用該特性的情況——它能解決的問題,以及不使用它所帶來的痛苦——然後再學習它是如何工作的。像往常一樣,真正理解的唯一方法,就是自己編寫乙個。所以去做吧,後浪們。

文源網路,僅供學習之用,侵刪。

適合初學者的python實際例子

最近在github上發現了乙個有意思的專案,很適合初學者學習python 學習一門語言剛開始的時候是很枯燥的,各種概念語法以及無聊的列印都會讓人失去更進一步學習的動力。很多同學在學習了一段時間之後甚至會懷疑學習語言的用處,因為總是寫不出東西,只會寫一些簡單的列印 這個叫做geekcomputers ...

Linux入門 適合初學者

學習linux也有一陣子了,這過程中磕磕撞撞的,遇到了問題,也解決了一些問題,學習的路子是曲折的,想總結點啥的,讓剛剛學習linux的不會望而生畏。技術的價值不在於這個技術有多麼高超,而在於技術本身給我們帶來什麼價值,所以很多時候我們學習乙個技術,不能盲目學,是為了使用這個技術,知道這個技術的使用場...

Linux入門 適合初學者

學習linux也有一陣子了,這過程中磕磕撞撞的,遇到了問題,也解決了一些問題,學習的路子是曲折的,想總結點啥的,讓剛剛學習linux的不會望而生畏。技術的價值不在於這個技術有多麼高超,而在於技術本身給我們帶來什麼價值,所以很多時候我們學習乙個技術,不能盲目學,是為了使用這個技術,知道這個技術的使用場...