# Module rational defines a class (a type) Rational, for rational numbers. # More operations (methods) can be added. class Rational: @staticmethod def _gcd(m, n): if n == 0: m, n = n, m while m != 0: m, n = n % m, m return n def __init__(self, num, den=1): if not isinstance(num, int) or not isinstance(den, int): raise TypeError if den == 0: raise ZeroDivisionError sign = 1 if num < 0: num, sign = -num, -sign if den < 0: den, sign = -den, -sign g = Rational._gcd(num, den) # call function gcd defined in this class. self._num = sign * (num//g) self._den = den//g def num(self): return self._num def den(self): return self._den def __add__(self, another): # mimic + operator num = (self._num * another.den() + self._den * another.num()) den = self._den * another.den() return Rational(num, den) def __mul__(self, another): # mimic * operator return Rational(self._num * another.num(), self._den * another.den()) def __floordiv__(self, another): # mimic // operator if another.num() == 0: raise ZeroDivisionError return Rational(self._num * another.den(), self._den * another.num()) # ... ... # Other operators can be defined similarly: # -:__sub__, /:__truediv__, %:__mod__, etc. def __radd__(self, another): # if not isinstance(another, int): raise TypeError another = Rational(another) num = (self._num * another.den() + self._den * another.num()) den = self._den * another.den() return Rational(num, den) def __eq__(self, another): return (self._num * another.den() == self._den * another.num()) def __lt__(self, another): return (self._num * another.den() < self._den * another.num()) # Other comparison operators can be defined similarly: # !=:__ne__, <=:__le__, >:__gt__, >=:__ge__ def __str__(self): return ("(" + str(self._num) + "/" + str(self._den) + ")") def print(self): print("(" + str(self._num) + "/" + str(self._den) + ")") def to_int(self): return self._num // self._den def to_float(self): return self._num / self._den @classmethod def create(cls, num, den, sign=1): # 假定三参数正确给定,建立化简的有理数 r = Rational.__new__(Rational) # 创建一个空的新有理数对象 g = Rational._gcd(num, den) r._num = sign * (num//g) r._den = den//g return r ### 如果计算函数理改用本函数构造有理数,调用形式应为: # return Rational.create(num, den) # return Rational.create(num, den, -1) if __name__ == '__main__': r1 = Rational(3, 5) r2 = Rational(7, 15) r3 = r1 + r2 r4 = r3 * Rational(5, 6) r1.print() r2.print() r3.print() r4.print() print(type(r1)) print(type(r1.print)) print() r5 = Rational(25, 40) r6 = Rational(1, -2) r7 = r1 + r6 r8 = r1 * Rational(-1, -2) r5.print() r6.print() r7.print() r8.print() print(r1, r2, r3, r4)