notimplementederror 是异常类,用于抽象基类中强制子类实现方法;notimplemented 是哨兵值,用于运算符重载中触发反射调用。两者类型、用途截然不同:前者抛出中断流程,后者返回启用协商机制。

NotImplementedError 是异常,NotImplemented 是哨兵值
两者类型完全不同:NotImplementedError 是一个继承自 Exception 的异常类,能被 try/except 捕获;而 NotImplemented 是 types.NotImplementedType 类型的唯一实例,不是异常,不能被抛出(raise NotImplemented 会直接报 TypeError)。
__eq__、__add__ 等二元方法必须返回 NotImplemented,不能 raise
当实现比较或算术运算符时,如果当前类型不支持该操作,应返回 NotImplemented,而不是抛异常。Python 解释器看到这个返回值后,会自动尝试调用另一个操作数的对应方法(例如 a.__eq__(b) 返回 NotImplemented,则接着调用 b.__eq__(a))。
- 错误写法:
def __eq__(self, other): raise NotImplementedError→ 会中断整个比较流程,无法 fallback - 正确写法:
def __eq__(self, other): return NotImplemented→ 允许 Python 尝试反射操作或降级逻辑 - 若所有相关方法都返回
NotImplemented,最终解释器才抛TypeError(如TypeError: unsupported operand type(s) for ==)
NotImplemented 在布尔上下文中已被禁用
从 Python 3.9 开始,把 NotImplemented 当作真值用(比如 if NotImplemented:)会触发 DeprecationWarning;到 Python 3.14(2026 年已发布),这行为已升级为直接抛 TypeError。
- 旧代码中常见误用:
if some_result is not NotImplemented:→ 正确,但注意is比较才安全 - 危险写法:
if some_result:或not NotImplemented→ 在 3.14+ 必炸 -
NotImplemented不是设计来参与逻辑判断的,它只服务于操作符分发机制
容易混淆的典型场景:抽象基类 vs 运算符重载
在抽象基类(ABC)中定义未实现方法时,用 raise NotImplementedError 是标准做法;但在自定义类型的 __lt__、__radd__ 等特殊方法里,返回 NotImplemented 才是正确信号。
- ABC 场景:
class Shape(metaclass=ABCMeta): @abstractmethod def area(self): raise NotImplementedError - 运算符场景:
def __mul__(self, other): return NotImplemented if not isinstance(other, (int, float)) else ... - 混用会导致:前者让子类强制实现,后者让 Python 尝试别的方式——目标完全不同
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











