
在Python中,NotImplemented并不是一个异常类,而是一个特殊的值,用于在二元操作中表示某个操作对于该类型的对象是不适用的。当Python的内置二元操作(如加法+、乘法*、比较操作==等)在自定义类型上被调用,且这些操作在当前类型上没有定义时,可以返回NotImplemented。这样做允许Python解释器尝试调用另一个操作数的相应特殊方法,以实现操作符的重载或跨类型的操作。
Python中的NotImplemented和NotImplementedError虽然听起来相似,但实际上它们在用途、类型和行为上都有着显著的区别。
在这个案例中,我们定义一个自定义的数值类型MyNumber,它支持与自身的加法操作,但不直接支持与其他类型(如int或float)的加法。我们通过返回NotImplemented来表明当前对象不支持与另一个操作数的直接加法,这样Python会尝试调用另一个操作数的__radd__方法(如果它存在的话)。
class MyNumber:  
    def __init__(self, value):  
        self.value = value  
  
    def __add__(self, other):  
        # 检查other是否是MyNumber的实例  
        if isinstance(other, MyNumber):  
            # 如果是,执行加法并返回新的MyNumber实例  
            return MyNumber(self.value + other.value)  
        # 如果不是,返回NotImplemented,让Python尝试调用other的__radd__  
        # 但注意,我们在这里不实现__radd__,只是演示NotImplemented的用法  
        return NotImplemented  
  
    # 通常不需要显式实现__radd__,除非有特定的需求  
    # 如果要支持与非MyNumber类型的加法,可以在这里实现  
  
# 创建两个MyNumber实例  
a = MyNumber(5)  
b = MyNumber(3)  
  
# MyNumber与MyNumber相加  
print(a + b)  # 输出: <__main__.MyNumber object at 0x...>(具体输出会依Python解释器和运行时环境而异)  
# 但为了演示,我们可以添加一个__repr__方法来显示值  
class MyNumber:  
    # ...(前面的代码保持不变)  
    def __repr__(self):  
        return f"MyNumber({self.value})"  
  
# 重新创建实例并尝试相加  
a = MyNumber(5)  
b = MyNumber(3)  
print(a + b)  # 输出: MyNumber(8)  
  
# 尝试将MyNumber与int相加(这通常不会成功,因为没有实现__radd__或适当的类型转换)  
try:  
    print(a + 10)  # 这将抛出TypeError,因为没有合适的方法来处理这种加法  
except TypeError as e:  
    print(e)  # 输出可能是:"unsupported operand type(s) for +: 'MyNumber' and 'int'"在这个案例中,我们定义一个简单的类SpecialObject,它只在某些情况下支持比较操作。我们将展示如何在不支持比较时返回NotImplemented。
class SpecialObject:  
    def __init__(self, value):  
        self.value = value  
  
    def __eq__(self, other):  
        # 仅当other也是SpecialObject且值相等时才认为相等  
        if isinstance(other, SpecialObject) and self.value == other.value:  
            return True  
        # 如果不满足条件,返回NotImplemented让Python尝试其他操作  
        return NotImplemented  
  
# 创建两个SpecialObject实例  
obj1 = SpecialObject(10)  
obj2 = SpecialObject(10)  
obj3 = SpecialObject(20)  
  
# 比较两个SpecialObject实例  
print(obj1 == obj2)  # 输出: True  
print(obj1 == obj3)  # 输出: False(实际上,由于__eq__返回NotImplemented,但这里我们故意让实例比较不相等的情况直接返回False作为示例)  
# 注意:实际上,如果__eq__返回NotImplemented,Python会尝试调用other的__eq__方法,  
# 但在这个例子中,我们没有这样做,只是简化了逻辑来演示概念。  
  
# 尝试将SpecialObject与int比较(这将导致TypeError,因为int没有处理来自SpecialObject的NotImplemented的逻辑)  
try:  
    print(obj1 == 10)  # 这将抛出TypeError,因为int的__eq__方法不知道如何处理来自SpecialObject的比较  
except TypeError as e:  
    print(e)  # 输出可能类似于:"unsupported operand type(s) for ==: 'SpecialObject' and 'int'"