2. 反向算术运算符重载
当运算符的左侧为内置类型,右侧为自定义类型进行算术运算符运算时,会出现TypeError错误。
因无法修改内置类型的代码来实现运算符重载,此时需要使用反向算术运算符的重载来完成重载。
反向算术运算符重载的方法
方法名
运算符和表达式
说明
__radd__(self, other)
other + self
加法
__rsub__(self, other)
other - self
减法
__rmul__(self, other)
other * self
乘法
__rtruediv__(self, other)
other / self
除法
__rfloordiv__(self, other)
other // self
整数(地板除)
__rmod__(self, other)
other % self
求余(取模)
__rpow__(self, other)
other ** self
幂
__rmatmul__(self, other)
other @ self
矩阵乘法
二元反向算术运算符重载的方法格式:
def __rxxx__(self, other):
....
说明
- 对于算术运算符, self 参数绑定运算符左侧的对象,other 绑定运算符右侧的对象。
- 对于反向算术运算符, self 参数绑定运算符右侧的对象,other 绑定运算符左侧的对象。
示例
没有重载反向算数运算符的 Vector3D 类在运行 v4 = 2 * v1
时报错。如
# 反向算术运算符重载 示例
class Vector3D:
'''用于描述三维向量的类!,x,y,z分别是向量的坐标位置!'''
def __init__(self, x, y, z):
self.x, self.y, self.z = x, y, z
def __repr__(self):
return f'Vector3D({self.x},{self.y},{self.z})'
def __mul__(self, other):
return Vector3D(self.x * other, self.y * other, self.z * other)
v1 = Vector3D(1, 2, 3)
v2 = Vector3D(4, 5, 6)
print("v1:", v1)
print("v2:", v2)
v4 = v1 * 2
print("v4:", v4) # Vector3D(2, 4, 6)
v4 = 2 * v1 # 等同于 2.__mul__(v1),但 int 类型不支持此操作。报错
print("v4:", v4) # Vector3D(2, 4, 6)
运行结果
v1: Vector3D(1,2,3)
v2: Vector3D(4,5,6)
v4: Vector3D(2,4,6)
Traceback (most recent call last):
File "/Users/weimz/Desktop/chapter_31/02_reverse_arithmetis_operator_overload.py", line 27, in <module>
v4 = 2 * v1 # 等同于 2.__mul__(v1),但 int 类型不支持此操作。报错
~~^~~~
TypeError: unsupported operand type(s) for *: 'int' and 'Vector3D'
重载反向算数运算符的方法 __rmul__
后,运行结果正常。如:
# 反向算术运算符重载 示例
class Vector3D:
'''用于描述三维向量的类!,x,y,z分别是向量的坐标位置!'''
def __init__(self, x, y, z):
self.x, self.y, self.z = x, y, z
def __repr__(self):
return f'Vector3D({self.x},{self.y},{self.z})'
def __mul__(self, other):
return Vector3D(self.x * other, self.y * other, self.z * other)
def __rmul__(self, other):
return self.__mul__(other)
v1 = Vector3D(1, 2, 3)
v2 = Vector3D(4, 5, 6)
print("v1:", v1)
print("v2:", v2)
v4 = v1 * 2
print("v4:", v4) # Vector3D(2, 4, 6)
v4 = 2 * v1 # 调用 v1.__rmul__(2), 结果正确。
print("v4:", v4) # Vector3D(2, 4, 6)
运行结果
v1: Vector3D(1,2,3)
v2: Vector3D(4,5,6)
v4: Vector3D(2,4,6)
v4: Vector3D(2,4,6)