1. 程式人生 > >Python一一運算子過載

Python一一運算子過載

基礎知識

      運算子過載讓類攔截常規的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)])    

執行結果:

有多個迭代器的物件