Python运算符重载
一、模拟数字类型运算重载
1.算术运算
运算符 | 正向方法 | 反向方法 | 就地方法 | 说明 |
---|---|---|---|---|
+ | __add__ | __radd__ | __iadd__ | 加法或拼接 |
- | __sub__ | __rsub__ | __isub__ | 减法 |
* | __mul__ | __rmul__ | __imul__ | 乘法或重复复制 |
/ | __truediv__ | __rtruediv__ | __itruediv__ | 除法 |
// | __floordiv__ | __rfloordiv__ | __ifloordiv__ | 整除 |
% | __mod__ | __rmod__ | __imod__ | 取模 |
divmod() | __divmod__ | __rdivmod__ | __idivmod__ | 返回由整除的商和模数组成的元组 |
**,pow() | __pow__ | __rpow__ | __ipow__ | 幂运算 |
@ | __matmul__ | __rmatmul__ | __imatmul__ | 矩阵乘法 |
2.比较运算
运算符 | 正向调用方法 | 反向调用方法 | 后备机制 |
---|---|---|---|
a == b | a.__eq__(b) | b.__eq__(a) | 返回id(a) == id( b) |
a != b | a.__ne__(b) | b.__ne__(a) | 返回not(a == b) |
a > b | a.__gt__(b) | b.__lt__(a) | 抛出TypeError |
a < b | a.__lt__(b) | b.__gt__(a) | 抛出TypeError |
a >= b | a.__ge__(b) | b.__le__(a) | 抛出TypeError |
a <= b | a.__le__(b) | b.__ge__(a) | 抛出TypeError |
示例:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
# 加法重载
def __add__(self, other):
x = self.x + other.x
y = self.y + other.y
return Vector(x, y)
# 就地加法重载
def __iadd__(self, other):
print("__iadd__ done!")
return self.__add__(other)
# 减法重载
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
# 求模长
def __abs__(self):
# return math.sqrt(self.x ** 2 + self.y ** 2)
return math.hypot(self.x, self.y)
# 输出重载
def __str__(self):
return "Vector(x={}, y={})".format(self.x, self.y)
v1 = Vector(2, 6)
v2 = Vector(4, 5)
print("v1+v2:", v1 + v2)
print("v1-v2:", v1 - v2)
v1 += v2
print("v1+=v2:", v1)
print("|v1|:", abs(v1))
运行结果
二、反向操作与就地操作
1.反向操作
执行a + b:
- 1.如果a有__add__方法,并且没有返回NotImplemented,调用a.__add__(b)则返回结果。
- 2.如果a没有__add__方法,或返回值是NotImplemented,则检查b是否有__radd__方法。如果有,并且没有返回NotImplemented,则调用b.__radd__(a)。
- 3.如果b没有__radd__方法,或者调用__radd__方法返回值是NotImplemented,则抛出异常。
示例:
class A:
# def __add__(self, other):
# print(type(other))
# print("A__add__ done!")
def __radd__(self, other):
print(type(other))
print("A__radd__ done!")
class B:
# def __add__(self, other):
# print(type(other))
# print("B__add__ done!")
def __radd__(self, other):
print(type(other))
print("B__radd__ done!")
a = A()
b = B()
a + b
b + a
运行结果
三、输出重载
__str__与__repr__区别:
- 1.__str__不存在的时候,print()会自动调用__repr__输出。
- 2.__str__面向用户,__repr__面向程序员。
- 3.__str__由print和str()调用,__repr__由repr()调用。
示例:
class Student:
def __init__(self, name):
self.name = name
def __repr__(self):
return "Student(%r)" % self.name
def __str__(self):
return "Name:%s" % self.name
s = Student("张三")
print(s)
str = repr(s)
print(str)
print(eval(str))
运行结果
- eval()方法:执行一个字符串表达式,并返回表达式的值。