Python __lt__() 方法

Python __lt__() 语法

__lt__() 是 Python 的一个特殊方法(又称 “魔法方法” 或 “双下划线方法”),它用于定义当两个对象进行 “小于(<)” 比较时,如何判断它们的大小。

当使用 “<” 运算符比较两个对象时,Python 会自动调用左侧操作数的 __lt__() 方法。

语法:

class MyObject:
    def __lt__(self, other):
        # 返回 True, False 或 NotImplemented
        return self.value < other.value

说明:

__lt__() 方法接收以下 2 个参数。

  • self(必选) :表示类的实例本身,即 “<” 运算符左侧的对象。
  • other(必选) :表示与 self 进行比较的另一个对象,即 “<” 运算符右侧的对象。

__lt__() 方法必须返回一个布尔值(True 或 False),用于表示比较的结果。如果不支持比较(比如类型不兼容),则应返回 NotImplemented。如果返回 NotImplemented,Python 可能会尝试调用 other 对象的 __gt__() 方法来尝试反向比较。

为了确保比较操作的一致性,我们通常建议在实现 __lt__() 时,也实现其他比较方法,如 __le__()、__eq__()、__ne__()、__gt__() 和 __ge__() 等。

提示:我们可以借助 functools.total_ordering 装饰器来自动实现其他比较方法。它只需要你实现 __eq__() 和任意一个方法,然后就可以自动生成所有其他比较方法。

Python __lt__() 摘要

属于 Python 魔法方法
使用频率
官方文档 查看
相关方法 __le__()__eq__()__ne__()__gt__()__ge__()

Python __lt__() 示例

接下来,我们通过几个简单的例子来讲解一下 Python __lt__() 方法是如何使用的。

示例 1:__lt__() 基本用法

class Score:
    def __init__(self, value):
        self.value = value

    def __lt__(self, other):
        if isinstance(other, Score):
            return self.value < other.value
        return NotImplemented     # 如果类型不兼容,返回 NotImplemented

# 创建 Score 类的实例
s1 = Score(85)
s2 = Score(90)
s3 = Score(85)

# 使用 < 运算符进行比较
print(s1 < s2)
print(s2 < s1)
print(s1 < s3)    # False,因为 85 不小于 85

运行结果如下。

True
False
False

分析:

在这个例子中,我们定义了一个 Score 类,并为其实现了 __lt__() 方法。当比较两个 Score 对象时,该方法比较它们内部的 value 属性。

示例 2:__lt__() 比较不同类型的对象

class MyNumber:
    def __init__(self, value):
        self.value = value

    def __lt__(self, other):
        if isinstance(other, MyNumber):
            return self.value < other.value
        elif isinstance(other, (int, float)):
            return self.value < other
        return NotImplemented

# 创建 MyNumber 类的实例
n = MyNumber(10)

# 与整数比较
print(n < 20)

# 与浮点数比较
print(n < 3.14)

# 与不支持的类型比较(会尝试反向操作)
try:
    print(n < "abc")
except TypeError as e:
    print(e)

运行结果如下。

True
False
'<' not supported between instances of 'MyNumber' and 'str'

分析:

在 MyNumber 类中,我们手动实现了 __lt__() 方法,用于处理与 MyNumber 实例以及内置的 int 和 float 类型之间的比较。

当与字符串 'abc' 比较时,由于 MyNumber 的 __lt__() 返回 NotImplemented,Python 会尝试进行反向比较。但字符串也没有定义如何与 MyNumber 实例进行 “大于” 比较,最终会引发 TypeError 异常。

示例 3:__lt__() 结合 functools.total_ordering

import functools

@functools.total_ordering
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):
        if not isinstance(other, Person):
            return NotImplemented
        return self.age == other.age

    def __lt__(self, other):
        if not isinstance(other, Person):
            return NotImplemented
        return self.age < other.age

    def __repr__(self):
        return f'Person({self.name}, {self.age})'

# 创建 Person 类的实例
p1 = Person('Jack', 30)
p2 = Person('Lucy', 25)
p3 = Person('Tony', 30)

# 使用 < 运算符
print(p1 < p2)     # False
print(p2 < p1)     # True
# 由于 @total_ordering,其他比较运算符也可用
print(p1 > p2)     # True
print(p1 == p3)    # True
print(p1 <= p3)    # True

运行结果如下。

False
True
True
True
True

分析:

通过使用 @functools.total_ordering 装饰器,我们只需要实现了 __eq__() 和 __lt__(),然后其他的比较运算符(如 >、==、<=)的行为都会由 total_ordering 自动推导出来。

例如,p1 > p2 会根据 p1 < p2 的结果进行推导,从而使得代码更加简洁。

上一篇: __ne__()

下一篇: __le__()

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号