python之算术运算符重载
什么是运算符重载
实际上,“运算符重载”只是意味着在类方法中拦截内置的操作,当类的实例出现在内置操作中,Python自动调用你的方法,并且你的方法的返回值变成了相应操作的结果。以下是对重载的关键概念的复习:
- 运算符重载让类拦截常规的Python运算。
- 类可重载所有Python表达式运算符
- 类可以重载打印、函数调用、属性点号运算等内置运算
- 重载使类实例的行为像内置类型。
- 重载是通过特殊名称的类方法来实现的。
算术运算符的重载
**算术运算符的重载表: **
方法名 | 运算符和表达式 | 说明 |
__add__(self,other ) | self + other | 加法 |
__sub__(self,other ) | self - other | 减法 |
__mul__(self,other ) | self * other | 乘法 |
__truediv__(self,other ) | self / other | 除法 |
__floordiv__(self,other ) | self //other | 整除 |
__mod__(self,other ) | self % other | 取模(求余) |
__pow__(self,other ) | self **other | 幂运算 |
反向运算符的重载
当运算符的左侧为内建类型时,右侧为自定义类型进行算术匀算符运算时会出现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 | 幂运算 |
复合赋值算术运算符的重载
复合赋值算术运算符 以x += y为例,此运算符会优先调用x.__iadd__(y)方法,如果没有__iadd__方法时,则会将复合赋值算术运算拆解为:x = x + y ,然后调用x = x.__add__(y)方法,如果再不存在__add__方法,则会触发TypeError类型的错误异常。
**复合赋值算术运算符的重载表: **
方法名 | 运算符和表达式 | 说明 |
__iadd__(self,other) | self += other | 加法 |
__isub__(self,other) | self -= other | 减法 |
__imul__(self,other) | self *= other | 乘法 |
__itruediv__(self,other) | self /= other | 除法 |
__ifloordiv__(self,other) | self //=other | 地板除 |
__imod__(self,other) | self %= other | 取模(求余) |
__ipow__(self,other) | self **=other | 幂运算 |
比较算术运算符的重载
**比较算术运算符的重载表: **
方法名 | 运算符和表达式 | 说明 |
__lt__(self,other) | self < other | 小于 |
__le__(self,other) | self <= other | 小于等于 |
__gt__(self,other) | self > other | 大于 |
__ge__(self,other) | self >= other | 大于等于 |
__eq__(self,other) | self == other | 等于 |
__ne__(self,other) | self != other | 不等于 |
实例:
class Fraction:
"分数"
def __init__(self, molecularK: int, denominator: int = None):
if not (isinstance(molecularK, int) and isinstance(denominator, int)):
raise TypeError("expect int")
if denominator == None:
self.integer = molecularK
elif molecularK == denominator:
self.integer = 1
else:
reduction = self.gcd(molecularK, denominator)
self.num = molecularK // reduction
self.den = denominator // reduction
def __str__(self):
# 在重写str方法时,不能用print,需要用return,改为如下代码形式就不再报错了
return str(self.num) + "/" + str(self.den)
def __add__(self, other):
if self.den == other.den:
new_num = self.num + other.num
return Fraction(new_num, self.den)
else:
new_den = self.den * other.den
new_num = (self.num * other.den) + (other.num * self.den)
return Fraction(new_num, new_den)
def __sub__(self, other):
"-"
if self.den == other.den:
new_num = self.num - other.num
return Fraction(new_num, self.den)
else:
new_den = self.den * other.den
new_num = (self.num * other.den) - (other.num * self.den)
return Fraction(new_num, new_den)
def __mul__(self, other):
"*"
new_num = self.num * other.num
new_den = self.den * other.den
return Fraction(new_num, new_den)
def __truediv__(self, other):
"/"
new_num = self.num * other.den
new_den = self.den * other.num
return Fraction(new_num, new_den)
def __gt__(self, other):
">"
first = self.num * other.den
two = self.den * other.num
return first > two
def __ge__(self, other):
">="
first = self.num * other.den
two = self.den * other.num
return first >= two
def __lt__(self, other):
"<"
first = self.num * other.den
two = self.den * other.num
return first < two
def __le__(self, other):
"<="
first = self.num * other.den
two = self.den * other.num
return first <= two
def __ne__(self, other):
"!="
first = self.num * other.den
two = self.den * other.num
return not first == two
def __eq__(self, other: object) -> bool:
"=="
first = self.num * other.den
two = self.den * other.num
return first == two
def gcd(self, a, b):
"""辗转相除法
"""
if a < b:
a, b = b, a
return a if b == 0 else self.gcd(b, a % b)
def get_num(self):
return self.num
def get_den(self):
return self.den
sample = Fraction(4, 5)
sample1 = Fraction(6, 9)
print(sample + sample1)
print(sample - sample1)
print(sample * sample1)
print(sample / sample1)
print(sample > sample1)
print(sample >= sample1)
print(sample < sample1)
print(sample <= sample1)
print(sample != sample1)
print(sample == sample1)
# =========== print ===========
22/15
2/15
8/15
6/5
True
True
False
False
True
False
未完待续……