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(d6d6_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)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。