Python一一運算子過載
阿新 • • 發佈:2019-01-26
基礎知識
運算子過載讓類攔截常規的Python運算。
類可過載所有Python表示式運算子。
類也可以過載列印、函式呼叫、屬性點號運算等內建運算。
過載使類例項的行為像內建型別。
過載是通過提供特殊名稱的類方法來實現的。
建構函式和表示式:__init__和__sub__
__init__:建構函式
__sub__:捕捉減法表示式
例如number.py如下:
class Number: def __init__(self, start): self.data = start def __sub__(self, other): return Number(self.data - other)
測試兩者:
from number import Number
X = Number(5)
Y = X - 2
print(Y.data)
執行結果:3
常見的運算子過載方法
索引和分片:__getitem__和__setitem__
對於例項的索引運算,會自動呼叫__getitem__。例如X[i]這樣的索引運算中,把X作為第一個引數傳遞,並且方括號內的索引值傳給第二個引數。
例項:
class Indexer: def __getitem__(self, item): return item ** 2 X = Indexer() print(X[2])
執行結果:4
攔截分片
分片表示式也用__getitem__
# __getitem__用於索引分片
class Indexer:
data = [5,6,7,8,9]
def __getitem__(self, item):
print('getitem:', item)
return self.data[item]
X = Indexer()
print(X[2])
print(X[2:4])
執行結果:
索引迭代:__getitem__
__getitem__也可以是Python中一種過載迭代的方式,如果定義了這個方法,for迴圈每次迴圈時都會呼叫類的__getitem__。
class stepper:
def __getitem__(self, item):
print("__getitem__ -> item:%s " % item)
return self.data[item]
X = stepper()
X.data = 'Spam'
print(X[1])
print('*********')
for item in X:
print(item)
執行結果:
任何支援for迴圈的類也會自動支援Python所有迭代環境,例如,成員關係測試in、列表解析、內建函式map、列表和元組賦值運算以及型別構造方法也會自動呼叫__getitem__(如果定義了的話)。
print('p' in X)
print(c for c in X)
print(list(map(str.upper,X)))
執行結果:
迭代器物件:__iter__和__next__
應該優先使用__iter__,它能夠比__getitem__更好地支援一般的迭代環境
使用者定義的迭代器
例項:
class Squares:
def __init__(self, start, stop):
self.value = start - 1
self.stop = stop
def __iter__(self):
return self
def __next__(self):
if self.value == self.stop:
raise StopIteration
self.value += 1
return self.value ** 2
for i in Squares(1,5):
print(i, end=' ')
執行結果:1 4 9 16 25
和__getitem__不同:__iter__只迴圈一次,而不是迴圈多次(每次新的迴圈,都得建立一個新的迭代器物件)
X = Squares(1,5)
print([n for n in X])
print([n for n in X])
print([n for n in Squares(1,5)])
執行結果: