太好用!教你幾招Python魔法方法的妙用
專注Python、AI、大資料,請關注公眾號七步程式設計!
Python是一種簡單的程式語言,滿足一個需求,可以有各種各樣的實現方法。正是因為它可以透過各種串聯滿足很多複雜的邏輯,因此,對程式碼可讀性關注度不高的開發者而言,會編寫出很多複雜而令人難以理解的程式碼。
Python語法本身雖然簡單,但是要想實現可讀性高,讓其他開發者能夠輕鬆理解的程式碼卻是一項需要長時間學習和加強的技能。
而在這眾多技能中,
魔法方法
(Magic Methods)便是其中一個很棒的選擇,它允許使用者在定義類的時候能夠使用內建運算子和關鍵字,讓使用類的方法更加直觀明瞭。
魔法方法
如果你已經使用了一段時間Python,那麼一定了解或者接觸過魔法方法。
魔法方法是一種以
雙下劃線
開頭和結尾的一種特殊方法,在使用類的時候非常常見,例如,經常會用到的
__init__
。它的功能是作為建構函式,能夠在類初始化時呼叫,你可以在初始化方法中定義一些初始化變數、初始化操作,當執行到類內部時,它會首先執行這些方法。
當然,魔法方法遠不至於
__init__
,為了幫助大家理解Python魔法方法的價值,本文就以一個示例來開始本文的講解。
下面透過實現一個名為
TimePeriod
的類,來看一下如何使用Python魔法方法使得程式碼更加清晰、可讀性更高。
基礎的TimePeriod類
下面
TimePeriod
主要實現2個方法:
時間的增加
時間的比較
基礎的實現方法大多會是下面這樣:
class TimePeriod: def __init__(self, hours=0, minutes=0): self。hours = hours self。minutes = minutes def add(self, other): minutes = self。minutes + other。minutes hours = self。hours + other。hours if minutes >= 60: minutes -= 60 hours += 1 return TimePeriod(hours, minutes) def greater_than(self, other): if self。hours > other。hours: returnTrue elif self。hours < other。hours: returnFalse elif self。minutes > other。minutes: returnTrue else: returnFalse
實現
add
和
greater_than
兩個方法,分別用於增加和對比時間大小。
或許,從這段程式碼中看不出有任何問題。接下來,我們使用這個類來看一下。
time_i_sleep = TimePeriod(9, 0)time_i_work = TimePeriod(0, 30)print(time_i_sleep。greater_than(time_i_work))# True
這段程式碼在執行的時候沒有任何問題,也不會報錯。但是,如果你想要執行更為複雜的操作,例如,2個時間段
加和
再和另外2個時間段的
加和
進行對比,類似於
A+B
與
C+D
進行比較,如果使用上述這個類,對比會是這樣的:
time_i_sleep。add(time_i_watch_netflix)。greater_than(time_i_work。add(time_i_do_chores))
這樣看上去是不是非常複雜?
即便是作為一名聰明的開發人員,把這段程式碼拆開執行,也會像下面這樣複雜:
time_spent_unproductively = time_i_sleep。add(time_i_watch_netflix)time_spent_productively = time_i_work。add(time_i_do_chores)time_spent_unproductively。greater_than(time_spent_productively)
魔法方法實現方式
其實在Python中,很容易就可以實現上述功能,Python內建的有2個魔方方法
__add__
和
__gt__
分別對應於
+
和
>
運算。
現在,透過魔法方法來修改一下上面的類:
class TimePeriod: def __init__(self, hours=0, minutes=0): self。hours = hours self。minutes = minutes def __add__(self, other): minutes = self。minutes + other。minutes hours = self。hours + other。hours if minutes >= 60: minutes -= 60 hours += 1 return TimePeriod(hours, minutes) def __gt__(self, other): if self。hours > other。hours: returnTrue elif self。hours < other。hours: returnFalse elif self。minutes > other。minutes: returnTrue else: returnFalse
現在,再來進行一下對比運算:
(time_i_sleep + time_i_watch_netflix) > (time_i_work + time_i_do_chores)
這樣看起來是不是更加容易理解和閱讀了?
除此之外,你還可以加入更多魔法方法,實現更為豐富的功能。
例如,你想比較2個時間是否相等,會用到
==
運算,這時候你可以使用魔法方法
__eq__
,具體實現如下:
def __eq__(self, other): return self。hours == other。hours and self。minutes == other。minutes
Python魔法方法不止有算術運算和和比較運算,還有其他很多豐富的功能。例如,
__str__
,可以建立易於理解類的字串。
def __str__(self): returnf“{self。hours} hours, {self。minutes} minutes”
如果你需要,還可以透過
__getitem__
把類轉化成字典:
def __getitem__(self, item): if item == ‘hours’: return self。hours elif item == ‘minutes’: return self。minutes else: raise KeyError()
這樣,可以把很多字典的優質特性加入到類中,可以像訪問字典一樣去訪問類的屬性。
其他
除了上述提到的一些魔法方法,Python還有很多魔法方法值得使用。本文不再逐一舉例,下面介紹一下一些常用方法的功能,需要的可以在以後編碼中用一下。
__new__
:初始化類的例項時會呼叫
__init__
方法,而在實際建立例項時會更早地呼叫
__new__
方法。
__call__
:
__call__
方法允許我們的例項像方法或函式一樣可呼叫。
__len__
:這允許你自定義Python內建
len()
函式。
__repr__
:這類似於
__str__
魔法方法,它允許你定義類的字串表示形式。但是,區別在於
__str__
是針對終端使用者的,它提供了一個更加使用者友好的非正式字串,而
__repr__
是針對開發人員的,並且可能包含有關類的內部狀態的更復雜的資訊。
__setitem__
:前面示例中我們已經看過
__getitem__
方法,它主要用於獲取鍵值,而
__setitem__
則用於設定鍵值。
__enter__
和
__exit__
:這兩種方法通常一起使用,可以將你的類用作上下文管理器,實現類似Python中
with
語句的功能。
總結
Python雖然語法方面簡單,但是要成為一名優秀的Python開發人員,需要持續學習和積累,不斷學習這些書籍和教程之外的知識,來提升你程式碼的規範性、可讀性,這些小技能都是需要留意、必不可少的。