Python3 操作符重载方法示例
基础知识
实际上,“运算符重载”只是意味着在类方法中拦截内置的操作……当类的实例出现在内置操作中,Python自动调用你的方法,并且你的方法的返回值变成了相应操作的结果。以下是对重载的关键概念的复习:
- 运算符重载让类拦截常规的Python运算。
- 类可重载所有Python表达式运算符
- 类可以重载打印、函数调用、属性点号运算等内置运算
- 重载使类实例的行为像内置类型。
- 重载是通过特殊名称的类方法来实现的。
换句话说,当类中提供了某个特殊名称的方法,在该类的实例出现在它们相关的表达式时,Python自动调用它们。正如我们已经学习过的,运算符重载方法并非必须的,并且通常也不是默认的;如果你没有编写或继承一个运算符重载方法,只是意味着你的类不会支持相应的操作。然而,当使用的时候,这些方法允许类模拟内置对象的接口,因此表现得更一致。
以下代码以Python3.6.1为例
操作符重载方法:类(class)通过使用特殊名称的方法(len(self))来实现被特殊语法(len())的调用
#coding=utf-8 #specialfuns.py操作符重载方法 #类(class)通过使用特殊名称的方法(__len__(self))来实现被特殊语法(len())的调用 #构造与析构方法 classdemo1: #构造方法,对象实例化时调用 def__init__(self): print("构造方法") #析构方法,对象被回收时调用 def__del__(self): print("析构方法") #new classdemo2(object): #__init__之前调用,一般用于重写父类的__new__方法,具体使用见类文章的元类代码部分(http://blog.csdn.net/rozol/article/details/69317339) def__new__(cls): print("new") returnobject.__new__(cls) #算术运算 classdemo3: def__init__(self,num): self.data=num #+ def__add__(self,other): returnself.data+other.data #- def__sub__(self,other): returnself.data-other.data #* def__mul__(self,other): returnself.data*other.data #/ def__truediv__(self,other): returnself.data/other.data #// def__floordiv__(self,other): returnself.data//other.data #% def__mod__(self,other): returnself.data%other.data #divmod() def__divmod__(self,other): #商(10/5),余数(10%5) returnself.data/other.data,self.data%other.data #** def__pow__(self,other): returnself.data**other.data #<< def__lshift__(self,other): returnself.data<> def__rshift__(self,other): returnself.data>>other.data #& def__and__(self,other): returnself.data&other.data #^ def__xor__(self,other): returnself.data^other.data #| def__or__(self,other): returnself.data|other.data classnone: def__init__(self,num): self.data=num #反算术运算符(a+b,若a不支持算术运算符,则寻找b的算术运算符)(注:位置变换,在原始函数名前+r) classdemo4: def__init__(self,num): self.data=num #+ def__radd__(self,other): returnother.data+self.data #- def__rsub__(self,other): returnother.data-self.data #* def__rmul__(self,other): returnother.data*self.data #/ def__rtruediv__(self,other): returnother.data/self.data #// def__rfloordiv__(self,other): returnother.data//self.data #% def__rmod__(self,other): returnother.data%self.data #divmod() def__rdivmod__(self,other): returnother.data/self.data,other.data%self.data #** def__rpow__(self,other): returnother.data**self.data #<< def__rlshift__(self,other): returnother.data< > def__rrshift__(self,other): returnother.data>>self.data #& def__rand__(self,other): returnother.data&self.data #^ def__rxor__(self,other): returnother.data^self.data #| def__ror__(self,other): returnother.data|self.data #增量赋值运算,(注:位置同原始函数,在原始函数名前+i) classdemo5(): def__init__(self,num): self.data=num #+= def__iadd__(self,other): returnself.data+other #-= def__isub__(self,other): returnself.data-other #*= def__imul__(self,other): returnself.data*other #/= def__itruediv__(self,other): returnself.data/other #//= def__ifloordiv__(self,other): returnself.data//other #%= def__imod__(self,other): returnself.data%other #**= def__ipow__(self,other): returnself.data**other #<<= def__ilshift__(self,other): returnself.data< >= def__irshift__(self,other): returnself.data>>other #&= def__iand__(self,other): returnself.data&other #^= def__ixor__(self,other): returnself.data^other #|= def__ior__(self,other): returnself.data|other #比较运算符 classdemo6: def__init__(self,num): self.data=num #< def__lt__(self,other): returnself.data def__gt__(self,other): returnself.data>other.data #>= def__ge__(self,other): returnself.data>=other.data #一元操作符 classdemo7: 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): returnabs(self.data) #~按位取反 def__invert__(self): return~self.data #complex()字符转数字 def__complex__(self): return1+2j #int()转为整数 def__int__(self): return123 #float()转为浮点数 def__float__(self): return1.23 #round()近似值 def__round__(self): return1.123 #格式化 classdemo8: #print()打印 def__str__(self): return"Thisisthedemo." #repr()对象字符串表示 def__repr__(self): return"Thisisademo." #bytes()对象字节字符串表现形式 def__bytes__(self): returnb"Thisisonedemo." #format()格式化 def__format__(self,format_spec): returnself.__str__() #属性访问 classdemo9: #获取(不存在)属性 def__getattr__(self): print("访问的属性不存在") #getattr()hasattr()获取属性 def__getattribute__(self,attr): print("访问的属性是%s"%attr) returnattr #setattr()设置属性 def__setattr__(self,attr,value): print("设置%s属性值为%s"%(attr,value)) #delattr()删除属性 def__delattr__(self,attr): print("删除%s属性"%attr) #=================================================================== #描述器(类(test1)的实例出现在属主类(runtest)中,这些方法才会调用)(注:函数调用,这些方法不会被调用) classtest1: 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)) returnself.value def__delete__(self,instance): print("delete%s%s"%(self,instance)) delself.value classtest2: 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)) returninstance.t1 def__delete__(self,instance): print("delete%s%s"%(self,instance)) delself.value classruntest: t1=test1() t2=test2() #--- #自定义property classproperty_my: def__init__(self,fget=None,fset=None,fdel=None): self.fget=fget self.fset=fset self.fdel=fdel #对象被获取(self自身,instance调用该对象的对象(demo9),owner调用该对象的对象类对象(demo9)) def__get__(self,instance,owner): print("get%s%s%s"%(self,instance,owner)) returnself.fget(instance) #对象被设置属性时 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) classdemo10: def__init__(self): self.num=None defsetvalue(self,value): self.num=value defgetvalue(self): returnself.num defdelete(self): delself.num x=property_my(getvalue,setvalue,delete) #=================================================================== #自定义容器 classlis: def__init__(self,*args): self.lists=args self.size=len(args) self.startindex=0 self.endindex=self.size #len()容器元素数量 def__len__(self): returnself.size; #lis[1]获取元素 def__getitem__(self,key=0): returnself.lists[key] #lis[1]=value设置元素 def__setitem__(self,key,value): pass #dellis[1]删除元素 def__delitem__(self,key): pass #返回迭代器 def__iter__(self): returnself #rversed()反向迭代器 def__reversed__(self): whileself.endindex>0: self.endindex-=1 yieldself[self.endindex] #next()迭代器下个元素 def__next__(self): ifself.startindex>=self.size: raiseStopIteration#控制迭代器结束 elem=self.lists[self.startindex] self.startindex+=1 returnelem #in/notin def__contains__(self,item): foriinself.lists: ifi==item: returnTrue returnFalse #yield生成器(执行一次返回,下次继续执行后续代码返回) defyielddemo(): num=0 while1:#1==True;0==False ifnum>=10: raiseStopIteration num+=1 yieldnum #能接收数据的生成器 defyielddemo_1(): while1: num=yield print(num) #with自动上下文管理 classwithdemo: def__init__(self,value): self.value=value #返回值为as之后的值 def__enter__(self): returnself.value #执行完成,退出时的数据清理动作 def__exit__(self,exc_type,exc_value,traceback): delself.value if__name__=="__main__": #构造与析构 d1=demo1() deld1 #new d2=demo2() #算术运算符 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) #反运算符 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) #增量赋值运算(测试时注释其他代码) 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) #一元操作符(测试时注释其他代码) 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)#=>设置a属性值为1 print(getattr(d9,"a"))#=>a/访问的属性是a print(hasattr(d9,"a"))#=>True/访问的属性是a delattr(d9,"a")#删除a属性 #--- d9.x=100#=>设置x属性值为100 print(d9.x)#=>x/访问的属性是x deld9.x#=>删除x属性 #描述器 r=runtest() r.t1=100#=><__main__.test1><__main__.runtest>100 print(r.t1)#=>200/<__main__.test1><__main__.runtest> delr.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> /<__main__.test1><__main__.runtest> delr.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> deld10.x#=><__main__.property_my><__main__.demo10> d10.num=200; print(d10.num)#=>200 deld10.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)) foriinlis: print(i) foriinreversed(lis): print(i) print(3inlis) print(7inlis) print(3notinlis) print(7notinlis) #yield生成器(可迭代对象Iterable) foriinyielddemo(): print(i) #--- iters=iter(yielddemo()) print(next(iters)) print(next(iters)) #---发送数据给生成器--- iters=yielddemo_1() next(iters) iters.send(6)#发送数据并执行 iters.send(10) #with自动上下文管理 withwithdemo("Lessismore!")ass: print(s)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。