python之運算子過載
- 運算子過載:
什麼是運算子過載
讓自定義的類生成的物件(例項)能夠使用運算子進行操作
作用:
讓自定義的例項像內建物件一樣進行運算子操作
讓程式簡潔易讀
對自定義物件將運算子賦予新的規則
算術運算子的過載:
方法名 運算子和表示式 說明
__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 冪運算
示例:
class Mynumber:
def __init__(self,v):
self.data = v
def __repr__(self): #消除兩邊的尖括號
return "Mynumber(%d)"%self.data
def __add__(self,other):
'''此方法用來制定self + other的規則'''
v = self.data + other.data
return Mynumber(v) #用v建立一個新的物件返回給呼叫者
def __sub__(self,other):
'''此方法用來制定self - other的規則'''
v = self.data - other.data
return Mynumber(v)
n1 = Mynumber(100)
n2 = Mynumber(200)
# n3 = n1 + n2
n3 = n1+n2 # n3 = n1.__add__(n2)
print(n3) #Mynumber(300)
n4 = n3 - n2 #等同於n4 = n3.__sub__(n2)
print("n4 = ",n4)
rhs(right hand side) 右手邊
說明:
運算子過載的方法的引數已經有了固定的含義,不建議改變原有的運算子的含義及引數的意義
二元運算子的過載方法格式:
def __xx__(self,other):
語句塊
練習:
實現兩個自定義列表的相加
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])
#試想能否實現以下操作
L5 = L1 * 3
print(L5) #MyList([1,2,3,1,2,3,1,2,3])
class Mylist:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return 'Mylist(%s)' % self.data
def __add__(self, lst):
return Mylist(self.data + lst.data)
def __mul__(self, rhs):
# rhs為int型別,不能用rhs.data
return Mylist(self.data * rhs)
L1 = Mylist([1, 2, 3])
L2 = Mylist([4, 5, 6])
L3 = L1 + L2
print(L3) # Mylist([1,2,3,4,5,6])
L4 = L2 + L1
print(L4) # Mylist([4,5,6,1,2,3])
L5 = L1 * 3
print(L5) # Mylist([1,2,3,1,2,3,1,2,3])
反向運算子的過載
當運算子的左側為內建型別時,右側為自定義型別進行算術勻算符運算時會出現TypeError錯誤,因為無法修改內建型別的程式碼 實現運算子過載,此時需要使用反向運算子的過載
反向算術運算子的過載:
方法名 運算子和表示式 說明
__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 冪運算
示例:
class Mylist:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return 'Mylist(%s)' % self.data
def __add__(self, lst):
print('__add__被呼叫')
return Mylist(self.data + lst.data)
def __mul__(self, rhs):
# rhs為int型別,不能用rhs.data
print('__mul__被呼叫')
return Mylist(self.data * rhs)
def __rmul__(self, lhs):
print("__rmul__被呼叫")
return Mylist(self.data * lhs)
L1 = Mylist([1, 2, 3])
L2 = Mylist([4, 5, 6])
L3 = 3 * L1
print(L3)
L1 += L2
print(L1)
L2 *= 3
print(L2)
複合賦值算術運算子的過載
以複合賦值算術運算子 x += y為例,此運算子會優先呼叫x.__iadd__(y)方法,如果沒有__iadd__方法時,則會將複合賦值算術運 算拆解為:x = x + y
然後呼叫x = x.__add__(y)方法,如果再不存在__add__方法則會觸發TypeError型別的錯誤異常
複合賦值算術運算子的過載:
方法名 運算子和表示式 說明
__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 冪運算
比較算術運算子的過載
比較算術運算子的過載:
方法名 運算子和表示式 說明
__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 不等於
位運算子過載
方法名 運算子和表示式 說明
__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 右移
反向位運算子過載
方法名 運算子和表示式 說明
__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 右移
複合賦值位相關運算子過載
方法名 運算子和表示式 說明
__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 右移
一元運算子的過載
方法名 運算子和表示式 說明
__neg__(self) - self 負號
__pos__(self) + self 正號
__invert__(self) ~ self 取反
語法:
class 類名:
def __xxx__(self):
pass
示例見:
class Mylist:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return 'Mylist(%s)' % self.data
def __neg__(self):
g = (-x for x in self.data)
return Mylist(g)
def __pos__(self):
g = (abs(x) for x in self.data)
return Mylist(g)
l1 = Mylist([1, -2, 3, -4, 5, -6])
l2 = - l1
print(l2)
l3 = +l1
print(l3)
in/not in 運算子過載
格式:
def __contains__(self,e):
語句
注: in / not in 返回布林值 True / False
當過載了__contains__後,in和not in運算子都可用
not in 運算子的返回值與 in相反
示例:
class Mylist:
def __init__(self, iterable=()):
self.data = list(iterable)
def __repr__(self):
return 'Mylist(%s)' % self.data
def __contains__(self, e):
return True if e in self.data else False
l1 = Mylist([1, 2, 3, 4, -5, 6])
if 2 in l1: # 等同於if l1.__contains__(4)
print('2在l1內')
else:
print('2不在l1內')
if -4 not in l1: # 等同於if not l1.__contains__(4)
print('-4不在l1內')
else:
print('-4在l1內')
索引和切片運算子過載方法:
方法名 運算子和表示式 說明
__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繫結[]內的元素'
print('i的值', i)
return self.__data[i] # 返回data繫結列表中的第i個元素
def __setitem__(self, i, v):
'''此方法可以讓自定義的列表支援索引賦值操作'''
print('__setitem__被呼叫,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('切片的起點是:', i.start)
print('切片的終點是:', i.stop)
print('切片的步長是:', i.step)
elif type(i) is str:
print('使用者正在用字串進行索引操作')
# 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建構函式
作用:
用於建立一個slice物件,此對於用於切片操作的傳值
格式:
slice(start = None,stop = None ,step = None)
slice物件的例項屬性:
start 切片的起始值,預設為None
stop 切片的終止值,預設為None
step 切片的步長,預設為None
特性屬性@property
實現其他語言所擁有的getter和setter功能
作用:
用來模擬一個屬性
通過@property裝飾器,可以對模擬屬性的賦值和取值加以控制
示例:
class Student:
def __init__(self, s):
self.__score = s
@property
def score(self):
print('getter被呼叫')
return self.__score
@score.setter
def setScore(self, s):
'''此方法用設定值加以限制以保證資料的準確性setter是用來資料的'''
if 0 <= s <= 100:
self.__score = s
def getScore(self, s):
'''getter只是用來獲取資料'''
return self.__score
s = Student(20)
# s.setScore(100)
score = s.score
print('成績是:', score)
相關文章
- 【python隨筆】之【運算子過載】Python
- Python 運算子過載Python
- 過載運算子
- 運算子過載
- C++過載的奧義之運算子過載C++
- [Lang] 運算子過載
- C++ 運算子過載C++
- C++——運算子過載C++
- C++運算子過載C++
- 開心檔之C++ 過載運算子和過載函式C++函式
- Javascript實現運算子過載JavaScript
- 指標運算子過載(* 和 ->)指標
- 12 Python物件導向程式設計:運算子過載Python物件程式設計
- python學習之運算子Python
- C++ 過載運算子和過載函式C++函式
- C++運算子過載詳解C++
- 過載運算子的常見方法
- 過載運算子、解構函式函式
- 瞭解下C# 運算子過載C#
- 重拾Kotlin(18)-運算子過載Kotlin
- 深入C++05:運算子過載C++
- C++中運算子的過載C++
- Python運算子Python
- Python 運算子優先順序 運算子Python
- 02python開發之基本運算子Python
- python的運算子Python
- python身份運算子Python
- Python 位運算子Python
- Python 海象運算子Python
- JS-11 運算子之布林運算子JS
- 常用的過載運算子你瞭解幾個?
- Kotlin教程(七)運算子過載及其他約定Kotlin
- C#運算子過載---逐步地分析與理解C#
- 手寫程式語言-實現運算子過載
- C++運算子過載的一些困惑C++
- 教你快速理解C++中的運算子過載C++
- C++學習筆記(二) 運算子過載C++筆記
- Python學習-算術運算子,賦值運算子和複合運算子Python賦值