用戶:Xyy23330121/Python/類的方法與Python的計算
學習了「類」之後,我們可以進一步了解 Python 的數據模型:Python 中一切內容、包括計算在內,都是由類和類的實例完成的。
以簡單的 len(s)
為例,我們查閱文檔,可以發現它實際上是調用了 s
的方法 s.__len__(self)
,並返回該方法的結果[1]。
甚至,連加減法在內,幾乎所有的 Python 運算都可以用類的方法來定義、修改。為篇幅起見,本頁面的內容被分為多個頁面。讀者可以在右側目錄中找到對應頁面。
此方法用於支持把對象當函數使用時的結果。我們看以下示例:
class prt:
def __call__(self, *arg):
print(*arg)
a = prt()
a(11,45,14) #输出:11 45 14
它除了第一個參數會自動傳入自身以外,與平常定義的函數基本沒有區別。
len
函數時可能會產生困惑。此方法用於支持 len(self)
。該方法必須返回對象的長度,並必須以一個非負的 int
類型來表示。如果返回的並非非負整數,則會報錯。
特別的,如果一個對象沒有定義 __bool__
方法,而其 __len__
方法返回的值為 0
。則它在布爾運算中,被視為 False
。
operator
模塊中,operator.length_hint()
函數所調用的方法。
此方法是為了優化性能而設置的,它必須返回對象長度的估計值——這個估計值並不要求正確無誤。返回的估計值必須為一個非負整數。
特別的,返回值也可以為 NotImplemented,這會被視作與 __length_hint__ 方法完全不存在時一樣處理。
此方法用於支持 self[key]
的操作。一般用於鍵的有三種:
- 整數(用於序列)
- slice 對象(用於序列)
- 字符串或其它不可變對象(主要用於字典)。
此方法的返回值,應當為讀者希望 self[key]
所返回的數值。和其它強制進行類型檢查的方法不同,此方法實際上可以返回任何值。
此方法用於支持 self[key] = value
的操作。在調用此方法時,應直接對 self
進行修改。
此方法用於支持 del self[key]
的操作。
在字符串章節,提到過 slice 索引。slice 對象就是用該種索引方式時,向 key
參數傳入的對象。
如果 key 的類型不正確,則應當引發 TypeError。 如果 key 為序列索引集合範圍以外的值(在進行任何負數索引的特殊解讀之後),則應當引發 IndexError。 對於 mapping 類型,如果 key 找不到(不在容器中),則應當引發 KeyError。
於是,解決 str.format
中,不支持負數索引和 slice 索引的方式是簡單的。使用:
class fixGetitem:
def __init__(self, obj):
self.obj = obj
def __getitem__(self, key):
if isinstance(key, str):
if ':' in key:
key_list = [(int(arg) if arg != "" else None) for arg in key.split(':')]
if len(key_list) == 2:
return self.obj[key_list[0]: key_list[1]]
return self.obj[key_list[0]: key_list[1]: key_list[2]]
return self.obj[int(key)]
return self.obj[key]
在傳入 str.format
的參數 s
時,如果有負數索引或 slice 索引的需要(且沒有字符串索引的需要時),直接改為傳入 fixGetitem(s)
就能解決該問題。讀者可以自行拓展此方法。
對於 dict 的子類,如果定義了該方法。則在 __getitem__(key)
找不到鍵 key
時,會嘗試調用 __missing__(key)
並返回 __missing__(key)
的值。
該方法應該且必須返回一個新的迭代器對象。如果不返回迭代器,則會報錯。
此方法可用於支持 iter
函數、for ... in
語句以及比較運算符 in
和 not in
。
該方法用於提升 reversed(self)
的效率和 / 或適用範圍。
如果定義了該方法,則該方法必須返回一個新的迭代器對象。它應當返回以逆序逐個迭代容器內所有對象的迭代器對象。
如果未定義該方法,則 reversed(self)
會使用 __len__
方法和 __getitem__
方法,按照類似列表的方式生成一個迭代器。
此方法用於支持 item in self
和 item not in self
。它返回一個布爾值。
如果未定義 __contains__
方法。上述運算將嘗試通過 __iter__
來迭代 self
中的元素來實現。
對於類型,我們也有類似索引的操作。泛型就是這種操作的結果。
泛型一般用於函數註釋中。具體參見 函數註釋#泛型 。
獲取泛型時調用的方法。這個方法會自動被視為是類方法,因此沒必要使用裝飾符 @classmethod
來裝飾。
此方法一般不由讀者定義,而是通過繼承的方式自動引入的。具體可以參見Python 文檔。