说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在 Python 中,NotImplemented 是一个特殊的常量,表示某个操作没有实现或者不支持。通常情况下,它被用于实现比较运算符重载时,以指示比较操作无法完成。当对象的类型不支持特定的比较操作时,Python 解释器会返回 NotImplemented。这样,开发者可以根据需要对比较操作进行处理。
NotImplemented 是一个 Python 内置的常量,我们不需要定义可以直接使用,它的类型也是专有的:
print(NotImplemented)
# NotImplemented
type(NotImplemented)
# NotImplementedType
示例如下:
class A(object):
def __lt__(self, other):
return NotImplemented
>>> A() < A()
'''
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: A() < A()
'''
再如:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def __gt__(self, other):
return self.area() > other.area()
# 实现大于操作符
if isinstance(other, Rectangle):
return self.area() > other.area()
else:
return NotImplemented
# 创建两个矩形对象
rect1 = Rectangle(5, 4)
rect2 = Rectangle(3, 6)
# 使用小于操作符比较矩形对象的面积
print(rect1 < rect2) # 输出 True
# 使用大于操作符比较矩形对象的面积
print(rect1 > rect2) # 输出 True
# 与不符的对象类型比较
print(rect1 > 300) # 输出 TypeError
我们实现了 Rectangle 类的 __lt__
方法和 __gt__
方法来支持小于操作符 < 和大于操作符 >。在 __gt__
方法中,我们检查 other 是否是 Rectangle 类的实例。如果是,我们比较两个矩形的面积。如果 other 不是 Rectangle 类的实例,我们返回 NotImplemented。这就使得 Python 解释器知道它应该尝试反转比较操作,以便使得两个对象之间的比较可以正常进行。
NotImplemented 用于表明运算没有针对其他类型的实现。
举个例子,如果你定义了一个类,并实现了 <
操作符重载,但是没有实现 > 操作符重载,那么当你尝试比较两个对象的大小关系时,如果第一个对象使用了 >
操作符,Python 解释器就会返回 NotImplemented,表明这个比较操作没有被支持。
NotImplemented
是 一个应当由双目运算特殊方法(如 __eq__()
, __lt__()
, __add__()
, __rsub__()
等)返回的特殊值,用来表明该运算没有针对其他类型的实现;也可由原地双目运算特殊方法(如 __imul__()
, __iand__()
等)出于同样的目的而返回。 它不应在布尔上下文中被求值。 NotImplemented 是 types.NotImplementedType
类型的唯一实例。
当我们进行对象间的比较时(调用对象的 __eq__
, __lt__
),如果对应的方法返回了 NotImplemented,则会从右操作数的角度调用方法进行比较。
应当由双目运算特殊方法(如 __eq__()
, __lt__()
, __add__()
, __rsub__()
等)返回的特殊值,用于表明运算没有针对其他类型的实现;也可由原地双目运算特殊方法(如 __imul__()
, __iand__()
等)出于同样的目的而返回。 它不应在布尔运算中被求值。 NotImplemented 是 types.NotImplementedType
类型的唯一实例。
当二进制(或就地)方法返回 NotImplemented
时,解释器将尝试对另一种类型(或其他一些回滚操作,取决于运算符)的反射操作。 如果所有尝试都返回 NotImplemented
,则解释器将引发适当的异常。 错误返回的 NotImplemented
将导致误导性错误消息或返回到Python代码中的 NotImplemented
值。
当一个双目(或原地)方法返回 NotImplemented 时解释器将尝试对另一种类型(或其他回退操作,具体取决于所用的运算符)的反射操作。 如果所有尝试都返回 NotImplemented,解释器将引发适当的异常。 错误地返回 NotImplemented 将导致误导性的错误消息或 NotImplemented 值被返回给 Python 代码。
NotImplementedError 和 NotImplemented 不可相互替代,即使它们有相似的名称和用途。 请参阅 NotImplementedError 了解其使用细节。
在 3.9 版本发生变更: 在布尔上下文件中对 NotImplemented 求值的操作已被弃用。 虽然它目前会被求解为真值,但将同时发出 DeprecationWarning。 它将在未来的 Python 版本中引发 TypeError。
例如在 Python 中对列表进行排序时,会经常间接使用像 __lt__()
这类比较运算的方法。
有时 Python 的内部算法会选择别的方法来确定比较结果,或者直接选择一个默认的结果。如果抛出一个异常,则会打破排序运算,因此如果使用 NotImplemented 则不会抛出异常,这样 Python 可以尝试别的方法。
NotImplemented 对象向运行时环境发出一个信号,告诉运行环境如果当前操作失败,它应该再检查一下其他可行方法。例如在 a == b 表达式,如果 a.__eq__(b)
返回 NotImplemented,那么 Python 会尝试 b.__eq__(a)
。如果调用 b 的 __eq__()
方法可以返回 True 或者 False,那么该表达式就成功了。如果 b.__eq__(a)
也不能得出结果,那么 Python 会继续尝试其他方法,例如使用 != 来比较。
django 字段排序的代码:
@total_ordering
class Field(object):
"""Base class for all field types"""
def __eq__(self, other):
# Needed for @total_ordering
if isinstance(other, Field):
return self.creation_counter == other.creation_counter
return NotImplemented
def __lt__(self, other):
# This is needed because bisect does not take a comparison function.
if isinstance(other, Field):
return self.creation_counter < other.creation_counter
return NotImplemented
更新时间:April 12, 2024, 2:43 p.m. 标签:python 常量 未实现