Python進階 - 特殊方法的使用
阿新 • • 發佈:2021-06-27
1.什麼是特殊方法?
特殊方法可以理解為在呼叫內建方法時,程式背後真正被呼叫的方法,通常以雙下劃線開頭和結尾,例如 __len__
,有些地方也稱其為"魔術方法"(Magic Method)。
比如,我們比較兩個數的大小時,一般都會使用大於號或小於號進行判斷:
# 命令列呼叫
>>> 1 < 2
True
實際上是在呼叫 __lt__()
方法:
# 命令列呼叫
>>> int.__lt__(1, 2)
True
2.特殊方法有什麼用?
既然程式都已經自動呼叫了,那它有什麼用呢?其實,它更多的用於我們自己編寫的類中。下面我們自行編寫一個向量類:
class Vector: def __init__(self, x=0, y=0): self.x = x # x座標 self.y = y # y座標
我們在建立好兩個向量例項後,發現單獨顯示的貌似時地址,將兩個向量相加時也直接報錯了,跟我們預想的完全不一樣:
# 命令列呼叫 >>> v1 = Vector(1, 1) >>> v1 <__main__.Vector object at 0x0000013C5E4CC9D0> >>> v2 = Vector(2, 3) >>> v2 <__main__.Vector object at 0x0000013C5E4CC8B0> >>> v1 + v2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'Vector' and 'Vector' >>>
這時候特殊方法就派上用場了。下面通過完善這個向量類,介紹幾款常用的特殊方法。
3.幾款常用的特殊方法
__repr__()
這個方法的主要作用是將一個物件用字串的形式輸出,便於我們進行辨認。
對於我們這個向量類,我們想讓每個向量例項都輸出成“Vector(m, n)”這樣的格式,所以我們就可以使用 __repr__()
方法進行定義:
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y def __repr__(self): # 定義Vector類的物件的字串返回格式 return 'Vector({}, {})'.format(self.x, self.y) # 輸出結果 >>> v1 = Vector(1, 1) >>> v1 Vector(1, 1)
可以看到,輸出的結果符合我們的預期。我們繼續通過幾個特殊方法來完成向量的模、加法以及數乘等操作:
from math import hypot
class Vector:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __repr__(self):
# 定義Vector類的物件的字串返回格式
return 'Vector({}, {})'.format(self.x, self.y)
def __abs__(self):
# 通過計算x,y座標的歐幾里得距離,返回向量的模
return hypot(self.x, self.y)
def __bool__(self):
# 判斷向量的模是否為0,從而進行布林運算
return bool(abs(self))
def __add__(self, other):
# 定義兩個向量的加法
x = self.x + other.x
y = self.y + other.y
return Vector(x, y)
def __mul__(self, scalar):
# 定義一個數scalar與向量的乘積
return Vector(self.x * scalar, self.y * scalar)
# 命令列呼叫
>>> v1 = Vector(1, 2) # 定義向量v1的座標為(1, 2)
>>> v2 = Vector(2, 2) # 定義向量v2的座標為(2, 2)
>>> v1
Vector(1, 2)
>>> v2
Vector(2, 2)
>>> v1 + v2 # 向量相加
Vector(3, 4)
>>> v1 * 3 # 向量的數乘
Vector(3, 6)
>>> abs(v1 + v2) # 求 v1 + v2 的模
5.0
>>> bool(v1) # 對向量v1進行布林運算True
>>> bool(Vector(0, 0)) # 對向量(0, 0)進行布林運算
False
通過對一系列特殊方法進行定義,我們基本上完成了向量的基本操作。這讓我們這個Vector類變得生動起來。
4.特殊方法的意義
通過在自定義的類中重寫一些原生類方法背後的特殊方法,可以使得自定義的類也擁有和原生類相同的訪問、操作方式,讓使用者儘量不會感受到自定義類與原生類的差異,從而保持語言上的一致性。
5.如何查詢特殊方法?
通過Python語言參考手冊的“Data Model”,可以查詢到83個特殊方法的名字,其中47個用於實現算術運算、位運算和比較操作。
注:文章內容出自《流暢的Python》第一章