什么是运算符重载:
让自定义的类生产的对象,能够使用运算符进行操作
运算符实际上调用方法
作用:
让自定义的类的实例对象,向内建对象一样进行运算符操作让程序简洁易读
对自定义对象将运算符抚恤新的规则
比如 L = [1, 2, 3]
L2 = [4,5,6]
L + L2 运算符重载
- 二元运算符重载
__add__(self,rhs):
self + rhs
__add__ +
__sub__ -
__mul__ *
__truediv__ /
__floordiv__ // 地板除
__mod__ %
__pow__ **
示例代码 MyNumber
class MyNumber:
def __init__(self, value):
self.data = value #用data保存数据
def __repr__(self):
return "Mynumber(%d)" % self.data
def __add__(self, other):
v = self.data + other.data
r = MyNumber(v)
return r
n1 = MyNumber(100)
n2 = MyNumber(200)
n3 = n1 + n2 # 请问这样的操作可以吗?
print(n3.data)
print(n1, '+', n2, '=', n3)
实例代码2
实现自定义两个列表的相加,依据列表是可以 +操作的
class MyList:
def __init__(self, iterable):
self.data = list(iterable)
def __repr__(self):
return "MyList (%s)" self.data
def __add__(self, rhs):
return MyList(self.data + rhs.data)
def __mul__(self, rhs):
return MyList(self.data * rhs)
def __rmul__(self,lhs):
return MyList(self.data * lhs)
def __imul__(self, rhs):
"""
这种不用创建新对象,这样对象的id不会变
"""
self.data *= rhs
return self
def __neg__(self):
L = [-x for x in self.data]
return MyList(L)
def __contains__(self,ele):
if ele in self.data:
return True
return False
def __getitem__(self,i):
if type(i) is int:
print("正在索引取值")
elif type(i) is slice:
print("正在切片取值")
return self.data[i]
def __setitem__(self):
self.data[I] = value
反向运算符的重载:
L2 = 2 * L1 这种情况需要反向运算符重载
__radd__(self, lhs)
__rmul__(self, lhs)
__rmod__(self, lhs)
L7 = 2 *L1 # L6 = L1.__rmul__(2)
复合运算符重载
__iadd__(self, rhs)
__imul__(self, rhs)
L = [1, 2, 3]
print(id(L))
L *= 3
print(id(L))
L *= 3
等价于L = L * 3
<
运算符不能在自定义对象之间使用,需要运算符重载
比较运算符
运算符和表达式
说明
__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 位与
__or__ self | rhs 位或
__xor__ self ^ rhs 异或
__lshift__ self << rhs 左移
__rshift__ self >> rhs 右移
反向位运算符重载 等
一元运算符的重载
__neg__(self) - 负
__pos__(self) + 正
__invert__(self) ~ 取反
in not in 运算符
L1 = MyList([1, -2, 3, -4, 5])
print(3 in L1) `会报错,L1不是可迭代对象`
__constains__(self,e) e in self e是否在self里
- 索引和切片的运算符的重载
__getitem__(self, i)
x =self[i]
__setitem__(self,i,v)
self[i] = v
__del__(self,i) 删除某一index对应的数据
del L1[3] 相当于 L1.__del__(3)
L1 = MyList(range(10))
a= L1[::2] 实际上是 L[slice(None,None,2)]
L1[::2] = "ABCDE" 等同于 L1.setitem(slice(None,None,2), "ABCDE")