MST
星途 面试题库

面试题:自定义类型在Python数值运算类型自动提升机制中的应用

假设你定义了一个自定义数值类型,如何使其融入Python的数值运算类型自动提升机制,即与内置数值类型(整数、浮点数等)进行混合运算时,能遵循类似的类型提升规则?请详细描述实现思路和关键步骤。
29.3万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

要使自定义数值类型融入Python的数值运算类型自动提升机制,需按以下思路和关键步骤实现:

实现思路

  1. 定义自定义数值类型类,在类中实现与内置数值类型进行运算的特殊方法。
  2. 遵循Python类型提升规则,当自定义类型与内置类型运算时,若自定义类型优先级低于内置类型,应将自定义类型转换为合适的内置类型进行运算,否则将内置类型转换为自定义类型进行运算。

关键步骤

  1. 定义类: 定义自定义数值类型的类,例如 MyNumber 类。
    class MyNumber:
        def __init__(self, value):
            self.value = value
    
  2. 实现加法运算: 实现与内置数值类型相加的特殊方法 __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)
    
  3. 实现其他运算: 类似地,实现减法(__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__}'")
    
  4. 类型比较: 实现比较方法,如 __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 就可以与内置数值类型进行混合运算,并遵循类似的类型提升规则。