python之運(yùn)算符重載,很重要一定要會
?運(yùn)算符重載:
? ? ? ? 什么是運(yùn)算符重載
? ? ? ? ? ? 讓自定義的類生成的對象(實(shí)例)能夠使用運(yùn)算符進(jìn)行操作
? ? ? ? 作用:
? ? ? ? ? ? 讓自定義的實(shí)例像內(nèi)建對象一樣進(jìn)行運(yùn)算符操作
? ? ? ? ? ? 讓程序簡潔易讀
? ? ? ? ? ? 對自定義對象將運(yùn)算符賦予新的規(guī)則
? ? ? ? 算術(shù)運(yùn)算符的重載:
? ? ? ? ? ? 方法名? ? ? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? 說明
? ? ? ? ? ? __add__(self,rhs)? ? ? ? self + rhs? ? ? ? 加法
? ? ? ? ? ? __sub__(self,rhs)? ? ? ? self - rhs? ? ? ? ?減法
? ? ? ? ? ? __mul__(self,rhs)? ? ? ? self * rhs? ? ? ? ?乘法
? ? ? ? ? ? __truediv__(self,rhs)? ?self / rhs? ? ? ? ? 除法
? ? ? ? ? ? __floordiv__(self,rhs)? self //rhs? ? ? ? ? 地板除
? ? ? ? ? ? __mod__(self,rhs)? ? ? ?self % rhs? ? ? ?取模(求余)
? ? ? ? ? ? __pow__(self,rhs)? ? ? ?self **rhs? ? ? ? ?冪運(yùn)算
? ? ? ? ? ??
? ? ? ? 示例:

?
rhs(right hand side) 右手邊
? ? ? ? 說明:
? ? ? ? ? ? 運(yùn)算符重載的方法的參數(shù)已經(jīng)有了固定的含義,不建議改變原有的運(yùn)算符的含義及參數(shù)的意義
? ? ? ? 二元運(yùn)算符的重載方法格式:
? ? ? ? ? ? def __xx__(self,other):
? ? ? ? ? ? ? ? 語句塊
? ? 練習(xí):
? ? ? ? 實(shí)現(xiàn)兩個自定義列表的相加
? ? ? ? class Mylist:
? ? ? ? ? ? def __init__(self,iterable=()):
? ? ? ? ? ? ? ? self.data = list(iterable)
? ? ? ? L1 = MyList([1,2,3])
? ? ? ? L2 = MyList([4,5,6])
? ? ? ? L3 = L1+L2
? ? ? ? print(L3)? #MyList([1,2,3,4,5,6])
? ? ? ? L4 = L2 + L3
? ? ? ? print(L4) #MyList([4,5,6,1,2,3])
? ? ? ? #試想能否實(shí)現(xiàn)以下操作
? ? ? ? L5 = L1 * 3
? ? ? ? print(L5)? #MyList([1,2,3,1,2,3,1,2,3])
?
反向運(yùn)算符的重載
? ? ? ? 當(dāng)運(yùn)算符的左側(cè)為內(nèi)建類型時,右側(cè)為自定義類型進(jìn)行算術(shù)勻算符運(yùn)算時會出現(xiàn)TypeError錯誤,因?yàn)闊o法修改內(nèi)建類型的代碼? ? ? ? ? 實(shí)現(xiàn)運(yùn)算符重載,此時需要使用反向運(yùn)算符的重載
? ? ? ? ? ? ?反向算術(shù)運(yùn)算符的重載:
? ? ? ? ? ? 方法名? ? ? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? ?說明
? ? ? ? ? ? __radd__(self,lhs)? ? ? ?lhs + self? ? ? ?加法
? ? ? ? ? ? __rsub__(self,lhs)? ? ? ?lhs - self? ? ? ?減法
? ? ? ? ? ? __rmul__(self,lhs)? ? ? ?lhs * self? ? ? ?乘法
? ? ? ? ? ? __rtruediv__(self,lhs)? ?lhs / self? ? ? ?除法
? ? ? ? ? ? __rfloordiv__(self,lhs)? lhs // self? ? ? 地板除
? ? ? ? ? ? __rmod__(self,lhs)? ? ? ?lhs % self? ? ? ?取模(求余)
? ? ? ? ? ? __rpow__(self,lhs)? ? ? ?lhs ** self? ? ? 冪運(yùn)算
? ? ? ? ? ??
? ? 示例:
?
復(fù)合賦值算術(shù)運(yùn)算符的重載
? ? ? ? 以復(fù)合賦值算術(shù)運(yùn)算符 x += y為例,此運(yùn)算符會優(yōu)先調(diào)用x.__iadd__(y)方法,如果沒有__iadd__方法時,則會將復(fù)合賦值算術(shù)運(yùn)? ? ? ? ? 算拆解為:x = x + y
? ? ? ? 然后調(diào)用x = x.__add__(y)方法,如果再不存在__add__方法則會觸發(fā)TypeError類型的錯誤異常
? ? ? ? 復(fù)合賦值算術(shù)運(yùn)算符的重載:
? ? ? ? 方法名? ? ? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? 說明
? ? ? ? __iadd__(self,rhs)? ? ? ?self += rhs? ? ? ? 加法
? ? ? ? __isub__(self,rhs)? ? ? ?self -= rhs? ? ? ? ?減法
? ? ? ? __imul__(self,rhs)? ? ? ?self *= rhs? ? ? ? ?乘法
? ? ? ? __itruediv__(self,rhs)? ?self /= rhs? ? ? ? 除法
? ? ? ? __ifloordiv__(self,rhs)? self //=rhs? ? ? ? 地板除
? ? ? ? __imod__(self,rhs)? ? ? ?self %= rhs? ? ?取模(求余)
? ? ? ? __ipow__(self,rhs)? ? ? ?self **=rhs? ? ? ?冪運(yùn)算
? ? 比較算術(shù)運(yùn)算符的重載
? ? ? ? 比較算術(shù)運(yùn)算符的重載:
? ? ? ? 方法名? ? ? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? 說明
? ? ? ? __lt__(self,rhs)? ? ? ?self < rhs? ? ? ? 小于
? ? ? ? __le__(self,rhs)? ? ? ?self <= rhs? ? ? ?小于等于
? ? ? ? __gt__(self,rhs)? ? ? ?self > rhs? ? ? ? 大于
? ? ? ? __ge__(self,rhs)? ? ? ?self >= rhs? ? ? ?大于等于
? ? ? ? __eq__(self,rhs)? ? ? ?self == rhs? ? ? ?等于
? ? ? ? __ne__(self,rhs)? ? ? ?self != rhs? ? ? ?不等于
? ? ? ??
? ? 位運(yùn)算符重載
? ? ? ? ? ? 方法名? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? ? 說明
? ? ? ? __and__(self,rhs)? ? ? ?self & rhs? ? ? ? ? ?位與
? ? ? ? __or__(self,rhs)? ? ? ? self | rhs? ? ? ? ? ? ? 位或
? ? ? ? __xor__(self,rhs)? ? ? ?self ^ rhs? ? ? ? ? ? ?位異或
? ? ? ? __lshift__(self,rhs)? ? self <<rhs? ? ? ? ? ? 左移
? ? ? ? __rshift__(self,rhs)? ? self >>rhs? ? ? ? ? ? 右移
? ? 反向位運(yùn)算符重載
? ? ? ? ? ? ? 方法名? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? ?說明
? ? ? ? __and__(self,lhs)? ? ? ?lhs & rhs? ? ? ? ? ? ?位與
? ? ? ? __or__(self,lhs)? ? ? ? ?lhs | rhs? ? ? ? ? ? ? ?位或
? ? ? ? __xor__(self,lhs)? ? ? ?lhs ^ rhs? ? ? ? ? ? ? ?位異或
? ? ? ? __lshift__(self,lhs)? ? lhs <<rhs? ? ? ? ? ? ? 左移
? ? ? ? __rshift__(self,lhs)? ? lhs >>rhs? ? ? ? ? ? ? 右移
? ? 復(fù)合賦值位相關(guān)運(yùn)算符重載
? ? ? ? ? ? 方法名? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? ? 說明
? ? ? ? __iand__(self,rhs)? ? ? ?self & rhs? ? ? ? ? 位與
? ? ? ? __ior__(self,rhs)? ? ? ? self | rhs? ? ? ? ? ? ? 位或
? ? ? ? __ixor__(self,rhs)? ? ? ?self ^ rhs? ? ? ? ? ? 位異或
? ? ? ? __ilshift__(self,rhs)? ? self <<rhs? ? ? ? ? ?左移
? ? ? ? __irshift__(self,rhs)? ? self >>rhs? ? ? ? ? ?右移
? ? ? ??
? ? 一元運(yùn)算符的重載
? ? ?方法名? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? ? 說明
? ? ?__neg__(self)? ? ? ? ?- self? ? ? ? ? ?負(fù)號
? ? ?__pos__(self)? ? ? ? ?+ self? ? ? ? ? ?正號
? ? ?__invert__(self)? ? ? ~ self? ? ? ? ? ?取反
? ? 語法:
? ? ? ? class 類名:
? ? ? ? ? ? def __xxx__(self):
? ? ? ? ? ? ? ? pass
? ? 示例見:

?
in/not in 運(yùn)算符重載
? ? ? ? 格式:
? ? ? ? ? ? def __contains__(self,e):
? ? ? ? ? ? ? ? 語句
? ? ? ? ? ? 注: in / not in 返回布爾值 True / False
? ? ? ? ? ? 當(dāng)重載了__contains__后,in和not in運(yùn)算符都可用
? ? ? ? ? ? not in 運(yùn)算符的返回值與 in相反
? ? ? ? 示例:? ? ? ?

?
?索引和切片運(yùn)算符重載方法:
? ? ? ? 方法名? ? ? ? ? ? ? ? ? 運(yùn)算符和表達(dá)式? ? ? ? ? ? ? 說明
? ? ? ? __getitem__(self,i)? ? ?x = self(i)? ? ? ? ? 索引/切片取值
? ? ? ? __setitem__(self,i,v)? ?self[i] = v? ? ? ? ? 索引/切片賦值
? ? ? ? __delitem__(self,i)? ? ?del self[i]? ? ? ? ? del語句刪除索引/切片
? ? ? ? 作用:
? ? ? ? ? ? 讓自定義的類型的對象能夠支持索引和切片操作
? ? ? ? 示例:?
class Mylist:
? ? def __init__(self, iterable=()):
? ? ? ? self.__data = list(iterable)
?
? ? def __repr__(self):
? ? ? ? return 'Mylist(%s)' % self.__data
?
? ? def __getitem__(self, i):
? ? ? ? '索引取值,i綁定[]內(nèi)的元素'
? ? ? ? print('i的值', i)
? ? ? ? return self.__data[i]? # 返回data綁定列表中的第i個元素
?
? ? def __setitem__(self, i, v):
? ? ? ? '''此方法可以讓自定義的列表支持索引賦值操作'''
? ? ? ? print('__setitem__被調(diào)用,i = ', i, 'v = ', v)
? ? ? ? self.__data[i] = v
?
? ? def __delitem__(self, i):
? ? ? ? del self.__data[i]? # self.__data.pop(i)
? ? ? ? return self
? ? ? ? if type(i) is int:
? ? ? ? ? ? print('用戶正在用索引取值')
? ? ? ? elif type(i) is slice:
? ? ? ? ? ? print('用戶正在用切片取值')
? ? ? ? ? ? print('切片的起點(diǎn)是:', i.start)
? ? ? ? ? ? print('切片的終點(diǎn)是:', i.stop)
? ? ? ? ? ? print('切片的步長是:', i.step)
? ? ? ? elif type(i) is str:
? ? ? ? ? ? print('用戶正在用字符串進(jìn)行索引操作')
? ? ? ? ? ? # raise KeyError
? ? ? ? return self.__data[i]? # 返回data綁定的第i個元素
?
?
l1 = Mylist([1, 2, 3, 4, -5, 6])
print(l1[3])? # 4
?
l1[3] = 400
print(l1)? # Mylist([1, 2, 3, 400, -5, 6])
?
del l1[3]
print(l1)? # Mylist([1, 2, 3, -5, 6])
?
print(l1[::2])? # [1,3,6]
slice構(gòu)造函數(shù)
? ? ? ? 作用:
? ? ? ? ? ? 用于創(chuàng)建一個slice對象,此對于用于切片操作的傳值
? ? ? ? 格式:
? ? ? ? ? ? slice(start = None,stop = None ,step = None)
? ? ? ? slice對象的實(shí)例屬性:
? ? ? ? ? ? start? 切片的起始值,默認(rèn)為None
? ? ? ? ? ? stop? ?切片的終止值,默認(rèn)為None
? ? ? ? ? ? step? ?切片的步長,默認(rèn)為None
?
特性屬性@property
? ? 實(shí)現(xiàn)其他語言所擁有的getter和setter功能
? ? 作用:
? ? ? ? 用來模擬一個屬性
? ? ? ? 通過@property裝飾器,可以對模擬屬性的賦值和取值加以控制
? ? 示例:

?
這里有我自己整理了一套最新的python系統(tǒng)學(xué)習(xí)教程,包括從基礎(chǔ)的python腳本到web開發(fā)、爬蟲、數(shù)據(jù)分析、數(shù)據(jù)可視化、機(jī)器學(xué)習(xí)等。想要這些資料的可以關(guān)注小年,并在后臺私信小年:“01”即可領(lǐng)取。