在廣闊的 Python 編程世界中,有一組特性經常被初學者忽視,但在該語言的生態系統中具有重要意義。
魔術方法是一組前置方法defiPython 中提供特殊語法功能的點。 通過開頭和結尾處的雙破折號很容易識別它們,例如 __init__, __call__, __len__
… ETC。
魔術方法允許自定義對象的行為類似於內置的 Python 類型。
在本文中,我們將重點介紹強大的 dunder 函數。 我們將探討它們的用途並討論它們的用途。
無論你是 Python 新手還是經驗豐富的程序員,本文旨在讓你全面了解 Dunder 函數,讓你的 Python 編碼體驗更高效、更愉快。
請記住,Python 的魔力不僅在於其簡單性和多功能性,還在於其強大的功能,如 Dunder 函數。
也許是所有功能中最基本的 dunder 功能。 這是每當我們創建(或顧名思義,初始化)一個新對象時 Python 自動調用的神奇方法。__init__
比薩類:
def __init__(自我,大小,澆頭):
self.size = 大小
self.toppings = 澆頭
# 現在讓我們創建一個披薩
my_pizza = Pizza('large', ['pepperoni', 'mushrooms'])
print(my_pizza.size) # 這將打印:large
print(my_pizza.toppings) # 這將打印:['pepperoni', 'mushrooms']
在此示例中,創建了一個名為 Pizza 的類。 我們設置我們的 __init__ 函數以包含在初始化時指定的參數,並將它們設置為我們自定義對象的屬性。
在這裡,它用來表示類的實例。 所以當我們寫 self.size = size 時,我們是在說,“嘿,這個披薩對像有一個屬性 size size
,我希望它是我在創建對象時提供的任何大小”。
這是Python的神奇方法,它允許我們 defi完成我們的定制項目的描述。
當您使用打印對像或將其轉換為字符串時 str()
, Python 檢查你是否有 defi我想出了一個方法 __str__
對於那個對象的類。
如果是這樣,請使用該方法將對象轉換為字符串。
我們可以擴展 Pizza 示例以包含一個函數 __str__
如下:
披薩類:def __init__(self, size, toppings): self.size = size self.toppings = toppings def __str__(self): return f"A {self.size} pizza with {', '.join(self.toppings )}" my_pizza = Pizza('large', ['pepperoni', 'mushrooms']) print(my_pizza) # 這將打印:一個大披薩配意大利辣香腸和蘑菇
__repr__
__str__ 函數更像是一種描述對象屬性的非正式方式。 另一方面,__repr__ 用於提供自定義對象的更正式、詳細和明確的描述。
如果你打電話 repr()
在一個對像上,或者你只是在控制台中輸入對象名稱,Python 將尋找一個方法 __repr__
.
Se __str__
它不是 defi晚上,Python會使用 __repr__
作為嘗試打印對像或將其轉換為字符串時的備份。 所以這通常是個好主意 defi至少完成 __repr__
,即使你不這樣做 defi出來 __str__
.
我們可以這樣做 defire __repr__
對於我們的披薩示例:
比薩類:
def __init__(自我,大小,澆頭):
self.size = 大小
self.toppings = 澆頭
def __repr__(自我):
返回 f"披薩 ('{self.size}', {self.toppings})"
my_pizza = Pizza('large', ['pepperoni', 'mushrooms'])
print(repr(my_pizza)) # 這將打印: Pizza('large', ['pepperoni', 'mushrooms'])
__repr__
為您提供一個字符串,您可以將其作為 Python 命令運行以重新創建比薩餅對象,而 __str__
給你一個更人性化的描述。 我希望它能幫助你更好地咀嚼這些愚蠢的方法!
在 Python 中,我們都知道可以使用運算符將數字相加 +
,如 3 + 5
.
但是如果我們想添加一些自定義對象的實例怎麼辦?
雙打功能 __add__
它使我們能夠做到這一點。 它使我們有能力 defi完成操作者的行為 +
在我們的個性化項目上。
為了保持一致性,我們假設我們想要 defi完成的行為 +
在我們的披薩示例中。 比方說,每當我們將兩個或多個比薩餅放在一起時,它會自動組合所有的配料。 它可能看起來像這樣:
比薩類:
def __init__(自我,大小,澆頭):
self.size = 大小
self.toppings = 澆頭
def __add__(自我,其他):
如果不是實例(其他,比薩餅):
提高類型錯誤(“你只能添加另一個披薩!”)
new_toppings = self.toppings + other.toppings
返回披薩(self.size,new_toppings)
# 讓我們創建兩個比薩餅
pizza1 = Pizza('large', ['pepperoni', 'mushrooms'])
pizza2 = Pizza('大', ['橄欖', '菠蘿'])
# 現在讓我們“添加”它們
組合披薩 = 披薩 1 + 披薩 2
print(combined_pizza.toppings) # 這將打印:['pepperoni', 'mushrooms', 'olives', 'pineapple']
類似於 dunder __add__
,我們還可以 defi完成其他算術函數,例如 __sub__
(通過使用運算符進行減法 -
)和 __mul__
(對於使用運算符的乘法 *
).
這種 dunder 方法使我們能夠 defi完成什麼功能 len()
必須返回我們的定制項目。
Python 使用 len()
獲取數據結構(如列表或字符串)的長度或大小。
在我們的例子中,我們可以說比薩餅的“長度”是它的配料數量。 以下是我們如何實現它:
比薩類:
def __init__(自我,大小,澆頭):
self.size = 大小
self.toppings = 澆頭
def __len__(自我):
返回 len(self.toppings)
# 讓我們創建一個披薩
my_pizza = Pizza('large', ['pepperoni', 'mushrooms', 'olives'])
print(len(my_pizza)) # 這將打印:3
在 __len__ 方法中,我們只返回列表的長度 toppings
。 現在, len(my_pizza)
它會告訴我們上面有多少配料 my_pizza
.
這個 dunder 方法允許對像是可迭代的,即它可以在 for 循環中使用。
為此,我們還必須 defi完成函數 __next__
, 這個用於 defi完成應該在迭代中返回下一個值的行為。 當序列中不再有元素時,它還應該向可迭代對象發出信號。 我們通常通過拋出異常來實現這一點 StopIteration
.
對於我們的披薩示例,假設我們想要迭代配料。 我們可以使 Pizza 類可迭代 defi一個方法 __iter__
:
比薩類:
def __init__(自我,大小,澆頭):
self.size = 大小
self.toppings = 澆頭
def __iter__(自我):
自我.n = 0
返回自我
定義 __next__(自我):
如果 self.n < len(self.toppings):
結果 = self.toppings[self.n]
自我.n += 1
返回結果
其他:
提高停止迭代
# 讓我們創建一個披薩
my_pizza = Pizza('large', ['pepperoni', 'mushrooms', 'olives'])
# 現在讓我們迭代它
用於 my_pizza 的配料:
打印(打頂)
在這種情況下,for 循環調用 __iter__
, 初始化一個計數器 (self.n)
並返回披薩對象本身 (self)
.
然後,for循環調用 __next__
依次獲得每個澆頭。
當 __next__
退回所有調味料, StopIteration
它拋出一個異常,並且 for 循環現在知道沒有更多的澆頭,因此將中止迭代過程。
Ercole Palmeri