面试题答案
一键面试要使自定义数值类型融入Python的数值运算类型自动提升机制,需按以下思路和关键步骤实现:
实现思路
- 定义自定义数值类型类,在类中实现与内置数值类型进行运算的特殊方法。
- 遵循Python类型提升规则,当自定义类型与内置类型运算时,若自定义类型优先级低于内置类型,应将自定义类型转换为合适的内置类型进行运算,否则将内置类型转换为自定义类型进行运算。
关键步骤
- 定义类:
定义自定义数值类型的类,例如
MyNumber
类。class MyNumber: def __init__(self, value): self.value = value
- 实现加法运算:
实现与内置数值类型相加的特殊方法
__add__
和__radd__
。__add__
用于自定义类型对象在左边的情况,__radd__
用于自定义类型对象在右边的情况。class MyNumber: def __init__(self, value): self.value = value def __add__(self, other): if isinstance(other, (int, float)): return MyNumber(self.value + other) elif isinstance(other, MyNumber): return MyNumber(self.value + other.value) else: raise TypeError(f"unsupported operand type(s) for +: '{type(self).__name__}' and '{type(other).__name__}'") def __radd__(self, other): return self.__add__(other)
- 实现其他运算:
类似地,实现减法(
__sub__
和__rsub__
)、乘法(__mul__
和__rmul__
)、除法(__truediv__
和__rtruediv__
)等运算的特殊方法。class MyNumber: def __init__(self, value): self.value = value def __add__(self, other): if isinstance(other, (int, float)): return MyNumber(self.value + other) elif isinstance(other, MyNumber): return MyNumber(self.value + other.value) else: raise TypeError(f"unsupported operand type(s) for +: '{type(self).__name__}' and '{type(other).__name__}'") def __radd__(self, other): return self.__add__(other) def __sub__(self, other): if isinstance(other, (int, float)): return MyNumber(self.value - other) elif isinstance(other, MyNumber): return MyNumber(self.value - other.value) else: raise TypeError(f"unsupported operand type(s) for -: '{type(self).__name__}' and '{type(other).__name__}'") def __rsub__(self, other): if isinstance(other, (int, float)): return MyNumber(other - self.value) else: raise TypeError(f"unsupported operand type(s) for -: '{type(other).__name__}' and '{type(self).__name__}'") def __mul__(self, other): if isinstance(other, (int, float)): return MyNumber(self.value * other) elif isinstance(other, MyNumber): return MyNumber(self.value * other.value) else: raise TypeError(f"unsupported operand type(s) for *: '{type(self).__name__}' and '{type(other).__name__}'") def __rmul__(self, other): return self.__mul__(other) def __truediv__(self, other): if isinstance(other, (int, float)): if other == 0: raise ZeroDivisionError return MyNumber(self.value / other) elif isinstance(other, MyNumber): if other.value == 0: raise ZeroDivisionError return MyNumber(self.value / other.value) else: raise TypeError(f"unsupported operand type(s) for /: '{type(self).__name__}' and '{type(other).__name__}'") def __rtruediv__(self, other): if isinstance(other, (int, float)): if self.value == 0: raise ZeroDivisionError return MyNumber(other / self.value) else: raise TypeError(f"unsupported operand type(s) for /: '{type(other).__name__}' and '{type(self).__name__}'")
- 类型比较:
实现比较方法,如
__eq__
(等于)、__ne__
(不等于)、__lt__
(小于)、__gt__
(大于)等,以支持自定义类型与内置数值类型的比较。class MyNumber: def __init__(self, value): self.value = value def __add__(self, other): if isinstance(other, (int, float)): return MyNumber(self.value + other) elif isinstance(other, MyNumber): return MyNumber(self.value + other.value) else: raise TypeError(f"unsupported operand type(s) for +: '{type(self).__name__}' and '{type(other).__name__}'") def __radd__(self, other): return self.__add__(other) def __sub__(self, other): if isinstance(other, (int, float)): return MyNumber(self.value - other) elif isinstance(other, MyNumber): return MyNumber(self.value - other.value) else: raise TypeError(f"unsupported operand type(s) for -: '{type(self).__name__}' and '{type(other).__name__}'") def __rsub__(self, other): if isinstance(other, (int, float)): return MyNumber(other - self.value) else: raise TypeError(f"unsupported operand type(s) for -: '{type(other).__name__}' and '{type(self).__name__}'") def __mul__(self, other): if isinstance(other, (int, float)): return MyNumber(self.value * other) elif isinstance(other, MyNumber): return MyNumber(self.value * other.value) else: raise TypeError(f"unsupported operand type(s) for *: '{type(self).__name__}' and '{type(other).__name__}'") def __rmul__(self, other): return self.__mul__(other) def __truediv__(self, other): if isinstance(other, (int, float)): if other == 0: raise ZeroDivisionError return MyNumber(self.value / other) elif isinstance(other, MyNumber): if other.value == 0: raise ZeroDivisionError return MyNumber(self.value / other.value) else: raise TypeError(f"unsupported operand type(s) for /: '{type(self).__name__}' and '{type(other).__name__}'") def __rtruediv__(self, other): if isinstance(other, (int, float)): if self.value == 0: raise ZeroDivisionError return MyNumber(other / self.value) else: raise TypeError(f"unsupported operand type(s) for /: '{type(other).__name__}' and '{type(self).__name__}'") def __eq__(self, other): if isinstance(other, (int, float)): return self.value == other elif isinstance(other, MyNumber): return self.value == other.value else: return False def __ne__(self, other): return not self.__eq__(other) def __lt__(self, other): if isinstance(other, (int, float)): return self.value < other elif isinstance(other, MyNumber): return self.value < other.value else: raise TypeError(f"unsupported operand type(s) for <: '{type(self).__name__}' and '{type(other).__name__}'") def __gt__(self, other): if isinstance(other, (int, float)): return self.value > other elif isinstance(other, MyNumber): return self.value > other.value else: raise TypeError(f"unsupported operand type(s) for >: '{type(self).__name__}' and '{type(other).__name__}'")
通过以上步骤,自定义数值类型 MyNumber
就可以与内置数值类型进行混合运算,并遵循类似的类型提升规则。