Python3 操作符重載方法示例
基礎(chǔ)知識
實際上,“運算符重載”只是意味著在類方法中攔截內(nèi)置的操作……當類的實例出現(xiàn)在內(nèi)置操作中,Python自動調(diào)用你的方法,并且你的方法的返回值變成了相應(yīng)操作的結(jié)果。以下是對重載的關(guān)鍵概念的復(fù)習(xí):
- 運算符重載讓類攔截常規(guī)的Python運算。
- 類可重載所有Python表達式運算符
- 類可以重載打印、函數(shù)調(diào)用、屬性點號運算等內(nèi)置運算
- 重載使類實例的行為像內(nèi)置類型。
- 重載是通過特殊名稱的類方法來實現(xiàn)的。
換句話說,當類中提供了某個特殊名稱的方法,在該類的實例出現(xiàn)在它們相關(guān)的表達式時,Python自動調(diào)用它們。正如我們已經(jīng)學(xué)習(xí)過的,運算符重載方法并非必須的,并且通常也不是默認的;如果你沒有編寫或繼承一個運算符重載方法,只是意味著你的類不會支持相應(yīng)的操作。然而,當使用的時候,這些方法允許類模擬內(nèi)置對象的接口,因此表現(xiàn)得更一致。
以下代碼以Python3.6.1為例
操作符重載方法: 類(class)通過使用特殊名稱的方法(len(self))來實現(xiàn)被特殊語法(len())的調(diào)用
#coding=utf-8 # specialfuns.py 操作符重載方法 # 類(class)通過使用特殊名稱的方法(__len__(self))來實現(xiàn)被特殊語法(len())的調(diào)用 # 構(gòu)造 與 析構(gòu) 方法 class demo1: # 構(gòu)造方法, 對象實例化時調(diào)用 def __init__(self): print("構(gòu)造方法") # 析構(gòu)方法, 對象被回收時調(diào)用 def __del__(self): print("析構(gòu)方法") # new class demo2(object): # __init__之前調(diào)用, 一般用于重寫父類的__new__方法, 具體使用見 類 文章的 元類 代碼部分(http://blog.csdn.net/rozol/article/details/69317339) def __new__(cls): print("new") return object.__new__(cls) # 算術(shù)運算 class demo3: def __init__(self, num): self.data = num # + def __add__(self, other): return self.data + other.data # - def __sub__(self, other): return self.data - other.data # * def __mul__(self, other): return self.data * other.data # / def __truediv__(self, other): return self.data / other.data # // def __floordiv__(self, other): return self.data // other.data # % def __mod__(self, other): return self.data % other.data # divmod() def __divmod__(self, other): # 商(10/5),余數(shù)(10%5) return self.data / other.data, self.data % other.data # ** def __pow__(self, other): return self.data ** other.data # << def __lshift__(self, other): return self.data << other.data # >> def __rshift__(self, other): return self.data >> other.data # & def __and__(self, other): return self.data & other.data # ^ def __xor__(self, other): return self.data ^ other.data # | def __or__(self, other): return self.data | other.data class none: def __init__(self, num): self.data = num # 反算術(shù)運算符(a+b, 若a不支持算術(shù)運算符,則尋找b的算術(shù)運算符)(注:位置變換, 在原始函數(shù)名前+r) class demo4: def __init__(self, num): self.data = num # + def __radd__(self, other): return other.data + self.data # - def __rsub__(self, other): return other.data - self.data # * def __rmul__(self, other): return other.data * self.data # / def __rtruediv__(self, other): return other.data / self.data # // def __rfloordiv__(self, other): return other.data // self.data # % def __rmod__(self, other): return other.data % self.data # divmod() def __rdivmod__(self, other): return other.data / self.data, other.data % self.data # ** def __rpow__(self, other): return other.data ** self.data # << def __rlshift__(self, other): return other.data << self.data # >> def __rrshift__(self, other): return other.data >> self.data # & def __rand__(self, other): return other.data & self.data # ^ def __rxor__(self, other): return other.data ^ self.data # | def __ror__(self, other): return other.data | self.data # 增量賦值運算,(注:位置同原始函數(shù),在原始函數(shù)名前+i) class demo5(): def __init__(self, num): self.data = num # += def __iadd__(self, other): return self.data + other # -= def __isub__(self, other): return self.data - other # *= def __imul__(self, other): return self.data * other # /= def __itruediv__(self, other): return self.data / other # //= def __ifloordiv__(self, other): return self.data // other # %= def __imod__(self, other): return self.data % other # **= def __ipow__(self, other): return self.data ** other # <<= def __ilshift__(self, other): return self.data << other # >>= def __irshift__(self, other): return self.data >> other # &= def __iand__(self, other): return self.data & other # ^= def __ixor__(self, other): return self.data ^ other # |= def __ior__(self, other): return self.data | other # 比較運算符 class demo6: def __init__(self, num): self.data = num # < def __lt__(self, other): return self.data < other.data # <= def __le__(self, other): return self.data <= other.data # == def __eq__(self, other): return self.data == other.data # != def __ne__(self, other): return self.data != other.data # > def __gt__(self, other): return self.data > other.data # >= def __ge__(self, other): return self.data >= other.data # 一元操作符 class demo7: def __init__(self, num): self.data = num # + 正號 def __pos__(self): return +abs(self.data) # - 負號 def __neg__(self): return -abs(self.data) # abs() 絕對值 def __abs__(self): return abs(self.data) # ~ 按位取反 def __invert__(self): return ~self.data # complex() 字符轉(zhuǎn)數(shù)字 def __complex__(self): return 1+2j # int() 轉(zhuǎn)為整數(shù) def __int__(self): return 123 # float() 轉(zhuǎn)為浮點數(shù) def __float__(self): return 1.23 # round() 近似值 def __round__(self): return 1.123 # 格式化 class demo8: # print() 打印 def __str__(self): return "This is the demo." # repr() 對象字符串表示 def __repr__(self): return "This is a demo." # bytes() 對象字節(jié)字符串表現(xiàn)形式 def __bytes__(self): return b"This is one demo." # format() 格式化 def __format__(self, format_spec): return self.__str__() # 屬性訪問 class demo9: # 獲取(不存在)屬性 def __getattr__(self): print ("訪問的屬性不存在") # getattr() hasattr() 獲取屬性 def __getattribute__(self, attr): print ("訪問的屬性是%s"%attr) return attr # setattr() 設(shè)置屬性 def __setattr__(self, attr, value): print ("設(shè)置 %s 屬性值為 %s"%(attr, value)) # delattr() 刪除屬性 def __delattr__(self, attr): print ("刪除 %s 屬性"%attr) # =================================================================== # 描述器(類(test1)的實例出現(xiàn)在屬主類(runtest)中,這些方法才會調(diào)用)(注:函數(shù)調(diào)用,這些方法不會被調(diào)用) class test1: def __init__(self, value = 1): self.value = value * 2 def __set__(self, instance, value): print("set %s %s %s"%(self, instance, value)) self.value = value * 2 def __get__(self, instance, owner): print("get %s %s %s"%(self, instance, owner)) return self.value def __delete__(self, instance): print("delete %s %s"%(self, instance)) del self.value class test2: def __init__(self, value = 1): self.value = value + 0.3 def __set__(self, instance, value): print("set %s %s %s"%(self, instance, value)) instance.t1 = value + 0.3 def __get__(self, instance, owner): print("get %s %s %s"%(self, instance, owner)) return instance.t1 def __delete__(self, instance): print("delete %s %s"%(self, instance)) del self.value class runtest: t1 = test1() t2 = test2() # --- # 自定義property class property_my: def __init__(self, fget=None, fset=None, fdel=None): self.fget = fget self.fset = fset self.fdel = fdel # 對象被獲取(self自身, instance調(diào)用該對象的對象(demo9), owner調(diào)用該對象的對象類對象(demo9)) def __get__(self, instance, owner): print("get %s %s %s"%(self, instance, owner)) return self.fget(instance) # 對象被設(shè)置屬性時 def __set__(self, instance, value): print("set %s %s %s"%(self, instance, value)) self.fset(instance, value) # 對象被刪除時 def __delete__(self, instance): print("delete %s %s"%(self, instance)) self.fdel(instance) class demo10: def __init__(self): self.num = None def setvalue(self, value): self.num = value def getvalue(self): return self.num def delete(self): del self.num x = property_my(getvalue, setvalue, delete) # =================================================================== # 自定義容器 class lis: def __init__(self, *args): self.lists = args self.size = len(args) self.startindex = 0 self.endindex = self.size # len() 容器元素數(shù)量 def __len__(self): return self.size; # lis[1] 獲取元素 def __getitem__(self, key = 0): return self.lists[key] # lis[1] = value 設(shè)置元素 def __setitem__(self, key, value): pass # del lis[1] 刪除元素 def __delitem__(self, key): pass # 返回迭代器 def __iter__(self): return self # rversed() 反向迭代器 def __reversed__(self): while self.endindex > 0: self.endindex -= 1 yield self[self.endindex] # next() 迭代器下個元素 def __next__(self): if self.startindex >= self.size: raise StopIteration # 控制迭代器結(jié)束 elem = self.lists[self.startindex] self.startindex += 1 return elem # in / not in def __contains__(self, item): for i in self.lists: if i == item: return True return False # yield 生成器(執(zhí)行一次返回,下次繼續(xù)執(zhí)行后續(xù)代碼返回) def yielddemo(): num = 0 while 1: # 1 == True; 0 == False if num >= 10: raise StopIteration num += 1 yield num # 能接收數(shù)據(jù)的生成器 def yielddemo_1(): while 1: num = yield print(num) # with 自動上下文管理 class withdemo: def __init__(self, value): self.value = value # 返回值為 as 之后的值 def __enter__(self): return self.value # 執(zhí)行完成,退出時的數(shù)據(jù)清理動作 def __exit__(self, exc_type, exc_value, traceback): del self.value if __name__ == "__main__": # 構(gòu)造與析構(gòu) d1 = demo1() del d1 # new d2 = demo2() # 算術(shù)運算符 d3 = demo3(3) d3_1 = demo3(5) print(d3 + d3_1) print(d3 - d3_1) print(d3 * d3_1) print(d3 / d3_1) print(d3 // d3_1) print(d3 % d3_1) print(divmod(d3, d3_1)) print(d3 ** d3_1) print(d3 << d3_1) print(d3 >> d3_1) print(d3 & d3_1) print(d3 ^ d3_1) print(d3 | d3_1) # 反運算符 d4 = none(3) d4_1 = demo4(5) print(d4 + d4_1) print(d4 - d4_1) print(d4 * d4_1) print(d4 / d4_1) print(d4 // d4_1) print(d4 % d4_1) print(divmod(d4, d4_1)) print(d4 ** d4_1) print(d4 << d4_1) print(d4 >> d4_1) print(d4 & d4_1) print(d4 ^ d4_1) print(d4 | d4_1) # 增量賦值運算(測試時注釋其他代碼) d5 = demo5(3) d5 <<= 5 d5 >>= 5 d5 &= 5 d5 ^= 5 d5 |= 5 d5 += 5 d5 -= 5 d5 *= 5 d5 /= 5 d5 //= 5 d5 %= 5 d5 **= 5 print(d5) # 比較運算符 d6 = demo6(3) d6_1 = demo6(5) print(d6 < d6_1) print(d6 <= d6_1) print(d6 == d6_1) print(d6 != d6_1) print(d6 > d6_1) print(d6 >= d6_1) # 一元操作符(測試時注釋其他代碼) d7 = demo7(-5) num = +d7 num = -d7 num = abs(d7) num = ~d7 print(num) print(complex(d7)) print(int(d7)) print(float(d7)) print(round(d7)) # 格式化 d8 = demo8() print(d8) print(repr(d8)) print(bytes(d8)) print(format(d8, "")) # 屬性訪問 d9 = demo9() setattr(d9, "a", 1) # => 設(shè)置 a 屬性值為 1 print(getattr(d9, "a")) # => a / 訪問的屬性是a print(hasattr(d9, "a")) # => True / 訪問的屬性是a delattr(d9, "a") # 刪除 a 屬性 # --- d9.x = 100 # => 設(shè)置 x 屬性值為 100 print(d9.x) # => x / 訪問的屬性是x del d9.x # => 刪除 x 屬性 # 描述器 r = runtest() r.t1 = 100 # => <__main__.test1> <__main__.runtest> 100 print(r.t1) # => 200 / <__main__.test1> <__main__.runtest> <class '__main__.runtest'> del r.t1 # => <__main__.test1> <__main__.runtest> r.t2 = 200 # => <__main__.test2> <__main__.runtest> 200 / <__main__.test1> <__main__.runtest> 200.3 print(r.t2) # => 400.6 / <__main__.test2> <__main__.runtest> <class '__main__.runtest'> / <__main__.test1> <__main__.runtest> <class '__main__.runtest'> del r.t2 # <__main__.test2> <__main__.runtest> # --- # 自定義property d10 = demo10() d10.x = 100; # => <__main__.property_my> <__main__.demo10> 100 print(d10.x) # => 100 / <__main__.property_my> <__main__.demo10> <class '__main__.demo10'> del d10.x # => <__main__.property_my> <__main__.demo10> d10.num = 200; print(d10.num) # => 200 del d10.num # 自定義容器(迭代器Iterator) lis = lis(1,2,3,4,5,6) print(len(lis)) print(lis[1]) print(next(lis)) print(next(lis)) print(next(lis)) for i in lis: print (i) for i in reversed(lis): print (i) print(3 in lis) print(7 in lis) print(3 not in lis) print(7 not in lis) # yield 生成器(可迭代對象Iterable) for i in yielddemo(): print (i) # --- iters = iter(yielddemo()) print(next(iters)) print(next(iters)) # --- 發(fā)送數(shù)據(jù)給生成器 --- iters = yielddemo_1() next(iters) iters.send(6) # 發(fā)送數(shù)據(jù)并執(zhí)行 iters.send(10) # with 自動上下文管理 with withdemo("Less is more!") as s: print(s)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python列表list操作符實例分析【標準類型操作符、切片、連接字符、列表解析、重復(fù)操作等】
- Python中operator模塊的操作符使用示例總結(jié)
- Python中的數(shù)學(xué)運算操作符使用進階
- 深入解析Python中的集合類型操作符
- python if not in 多條件判斷代碼
- python條件和循環(huán)的使用方法
- Python中條件判斷語句的簡單使用方法
- Python的條件語句與運算符優(yōu)先級詳解
- Python中條件選擇和循環(huán)語句使用方法介紹
- Python 條件判斷的縮寫方法
- Python入門篇之條件、循環(huán)
- Python3.4學(xué)習(xí)筆記之常用操作符,條件分支和循環(huán)用法示例
相關(guān)文章
利用Python3實現(xiàn)統(tǒng)計大量單詞中各字母出現(xiàn)的次數(shù)和頻率的方法
這篇文章主要介紹了利用Python3實現(xiàn)統(tǒng)計大量單詞中各字母出現(xiàn)的次數(shù)和頻率,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03在Python中操作字符串之startswith()方法的使用
這篇文章主要介紹了在Python中操作字符串之startswith()方法的使用,是Python入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-05-05使用 Django Highcharts 實現(xiàn)數(shù)據(jù)可視化過程解析
這篇文章主要介紹了使用 Django Highcharts 實現(xiàn)數(shù)據(jù)可視化過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-07-07舉例講解Python設(shè)計模式編程的代理模式與抽象工廠模式
這篇文章主要介紹了Python編程的代理模式與抽象工廠模式,文中舉了兩個簡單的小例子來說明這兩種設(shè)計模式的思路在Python編程中的體現(xiàn),需要的朋友可以參考下2016-01-01Python NumPy創(chuàng)建數(shù)組方法
這篇文章主要介紹了Python NumPy創(chuàng)建數(shù)組方法,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-09-09