自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

每個程序員都應該知道的11個Python魔術方法

譯文
開發(fā)
想要在Python類中支持內(nèi)置函數(shù)和方法調(diào)用的行為嗎?Python中的魔術方法可以讓您做到這一點!本文揭開魔術方法背后的魔法。

譯者 | 布加迪

審校 | 重樓

Python中,魔術方法Magic Method)可以幫助您模擬Python類中內(nèi)置函數(shù)的行為。這些方法前后雙下劃線__,因此也被稱為Dunder方法。

這些魔術方法還可以幫助您在Python中實現(xiàn)操作符重載。您可能見過這樣的例子,就像兩個整數(shù)與乘法運算符*一起使用得到乘積一樣。當它與字符串和整數(shù)k一起使用時,字符串會重復k

>>> 3 * 4
12
>>> 'code' * 3
'codecodecode'

我們在本文中將通過創(chuàng)建一個簡單的二維向量Vector2D類來探索Python中的魔術方法。

我們將從您可能熟悉的方法入手,逐步構建更有幫助的魔術方法。

不妨開始編寫一些魔術方法!

1. __init__

考慮下面的Vector2D

class Vector2D:
 pass

一旦創(chuàng)建了類,并實例化對象,就可以添加如下屬性obj_name.attribute_name = value。

然而,您需要在實例化對象時初始化這些屬性,而不是手動向創(chuàng)建的每個實例添加屬性當然,這一點也不有趣?。?/span>。

為此,您可以定義__init__方法。不妨Vector2D類定義__init__方法

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

v = Vector2D(3, 5)

2. __repr__

當您嘗試檢查或打印輸出實例化的對象時,您將發(fā)現(xiàn)沒有得到任何有幫助的信息。

v = Vector2D(3, 5)
print(v)

Output >>> <__main__.Vector2D object at 0x7d2fcfaf0ac0>

這就是為什么您應該添加一個表示字符串,一個對象的字符串表示。為此,添加__repr__方法,如下所示

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

v = Vector2D(3, 5)
print(v)


Output >>> Vector2D(x=3, y=5)

__repr__應該包含創(chuàng)建類實例所需的所有屬性和信息。__repr__方法通常用于調(diào)試目的。

3. __str__

__str__也用于添加對象的字符串表示。通常,__str__方法用于類的最終用戶提供信息。

不妨給我們的類添加一個__str__方法

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __str__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

v = Vector2D(3, 5)
print(v)


Output >>> Vector2D(x=3, y=5)

如果沒有__str__的實現(xiàn),它就返回到__repr__。因此對于您創(chuàng)建的每個類,您至少應該添加__repr__方法。

4. __eq__

接下來,不妨添加一個方法來檢查Vector2D類的任意兩個對象是否相等。如果兩個向量有相同的x和y坐標,它們是相等的。

現(xiàn)在創(chuàng)建兩個具有相等x和y值的Vector2D對象,并比較它們是否相等

v1 = Vector2D(3, 5)
v2 = Vector2D(3, 5)
print(v1 == v2)

結果為False,因為默認情況下比較會檢查內(nèi)存中對象ID是否相等。

Output >>> False

不妨添加__eq__方法來檢查是否相等

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __eq__(self, other):
 return self.x == other.x and self.y == other.y

檢查相等性現(xiàn)在應該按預期工作

v1 = Vector2D(3, 5)
v2 = Vector2D(3, 5)
print(v1 == v2)


Output >>> True 

5. __len__

Python的內(nèi)置len()函數(shù)可以幫助您計算內(nèi)置可迭代對象(iterable)的長度。比如說,向量而言,length應該返回該向量所包含的元素的個數(shù)。

所以不妨為Vector2D類添加一個__len__方法

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __len__(self):
 return 2

v = Vector2D(3, 5)
print(len(v))

Vector2D類的所有對象長度為2

Output >>> 2

6. __add__

現(xiàn)在不妨考慮對向量執(zhí)行的常見運算。不妨添加魔術方法來加減任意兩個向量。

如果直接嘗試添加兩個向量對象,就會遇到錯誤。所以您應該添加一個__add__方法

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __add__(self, other):
 return Vector2D(self.x + other.x, self.y + other.y)

您現(xiàn)在可以像這樣添加任意兩個向量

v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)
result = v1 + v2
print(result)


Output >>> Vector2D(x=4, y=7)

7. __sub__

下來,不妨添加一個__sub__方法來計算Vector2D類的任意兩個對象之間的差異

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __sub__(self, other):
 return Vector2D(self.x - other.x, self.y - other.y)


v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)
result = v1 - v2
print(result)


Output >>> Vector2D(x=2, y=3)

8. __mul__

我們還可以定義__mul__方法來定義對象之間的乘法。

不妨來處理

  • 標量乘法向量與標量的乘法
  • 內(nèi)積兩個向量的點積
class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __mul__(self, other):
 # Scalar multiplication
 if isinstance(other, (int, float)):
 return Vector2D(self.x * other, self.y * other)
 # Dot product
 elif isinstance(other, Vector2D):
 return self.x * other.x + self.y * other.y
 else:
 raise TypeError("Unsupported operand type for *")

現(xiàn)在我們將舉幾個例子,看看__mul__方法是如何實際工作的。

v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)

# Scalar multiplication
result1 = v1 * 2
print(result1) 
# Dot product
result2 = v1 * v2
print(result2)


Output >>>

Vector2D(x=6, y=10)
13

9. __getitem__

__getitem__魔術方法可以索引對象,并使用熟悉的方括號[]語法訪問屬性或屬性切片。

對于Vector2D類的對象v:

  • v [0]x坐標
  • v [1]y坐標

如果您嘗試通過索引訪問,您會遇到錯誤

v = Vector2D(3, 5)
print(v[0],v[1])


---------------------------------------------------------------------------

TypeError  Traceback (most recent call last)

 in ()
----> 1 print(v[0],v[1])

TypeError: 'Vector2D' object is not subscriptable

不妨實現(xiàn)__getitem__ 方法:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __getitem__(self, key):
 if key == 0:
 return self.x
 elif key == 1:
 return self.y
 else:
 raise IndexError("Index out of range")

現(xiàn)在您可以使用索引訪問這些元素,如下所示

v = Vector2D(3, 5)
print(v[0]) 
print(v[1])


Output >>>

3
5

10. __call__

借助__call__方法的實現(xiàn),您可以像調(diào)用函數(shù)一樣調(diào)用對象。

在Vector2D類中,我們可以實現(xiàn)__call__,按給定因子縮放

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __call__(self, scalar):
 return Vector2D(self.x * scalar, self.y * scalar)

如果您現(xiàn)在調(diào)用3,會得到縮放3向量:

v = Vector2D(3, 5)
result = v(3)
print(result)


Output >>> Vector2D(x=9, y=15)

11. __getattr__

__getattr__方法用于獲取對象的特定屬性的值。

這個例子而言,我們可以添加一個__getattr__ dunder方法,一旦被調(diào)用可計算向量的量值(L2-norm):

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __getattr__(self, name):
 if name == "magnitude":
 return (self.x ** 2 + self.y ** 2) ** 0.5
 else:
 raise AttributeError(f"'Vector2D' object has no attribute '{name}'")

不妨驗證這是否像預期的那樣工作

v = Vector2D(3, 4)
print(v.magnitude)


Output >>> 5.0

結論

這就是本教程的全部內(nèi)容!希望您已經(jīng)學了如何為您的類添加魔術方法,以模擬內(nèi)置函數(shù)的行為。

我們已介紹了一些最有用的魔術方法,但這并非詳盡的清單。為了進一步理解,您可以創(chuàng)建一個所選擇的Python類,根據(jù)所需的功能添加魔術方法。最后祝編程愉快!

原文標題:Harness the Power of AI for Business,作者:Bala Priya C

責任編輯:華軒 來源: 51CTO
相關推薦

2012-02-28 10:52:13

2018-03-07 12:57:53

2022-09-11 15:20:05

程序員命令開發(fā)

2012-10-11 10:32:48

Linux命令程序員

2024-04-24 14:52:26

JavaScriptWeb 開發(fā)

2021-10-18 10:21:28

程序員技能優(yōu)化

2020-09-03 12:54:37

Python程序員macOS

2023-01-31 15:43:47

2024-04-10 12:36:41

硬件代碼

2023-06-27 00:04:10

程序員JavaScript

2015-04-16 10:26:51

程序員 Python Ruby

2011-07-25 10:09:57

Python

2023-11-02 14:21:06

2021-08-19 15:14:29

程序員電子表格Airtable

2021-10-20 06:05:01

編程語言開發(fā)

2013-03-20 17:58:41

虛擬內(nèi)存程序員

2014-07-16 09:34:44

2017-04-05 12:04:17

python函數(shù)

2018-05-03 08:45:58

Linux命令

2011-06-16 08:58:57

軟考程序員
點贊
收藏

51CTO技術棧公眾號