苦练Python第54天:比较运算魔术方法全解析,让你的对象“懂大小、能排序”!

前言

大家好,我是 倔强青铜三 。欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!

欢迎来到 苦练Python第54天

今天咱们要深入探索Python类中的 比较运算魔术方法,这可是让你的对象**"懂大小、能排序"**的关键所在!

这些魔术方法包括:__lt____le____eq____ne____gt____ge____hash__

一口气吃透它们,你的类就能在比较、排序、集合操作中如鱼得水!


比较运算魔术方法全家福

方法 触发场景 作用
__lt__ a < b 小于
__le__ a <= b 小于等于
__eq__ a == b 等于
__ne__ a != b 不等于
__gt__ a > b 大于
__ge__ a >= b 大于等于
__hash__ hash(a) 计算对象的哈希值

__lt__:小于操作

作用

定义对象的"小于"逻辑,用于比较两个对象的大小。

触发场景

当你写下 a < b 时,Python会调用 a.__lt__(b)

示例

python 复制代码
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def __lt__(self, other):
        """触发场景:s1 < s2"""
        print("__lt__ 被调用!")
        return self.score < other.score

s1 = Student("张三", 85)
s2 = Student("李四", 90)
print(s1 < s2)  # __lt__ 被调用! -> True

__le__:小于等于操作

作用

定义对象的"小于等于"逻辑。

触发场景

当你写下 a <= b 时,Python会调用 a.__le__(b)

示例

python 复制代码
class Student:
    ...
    def __le__(self, other):
        """触发场景:s1 <= s2"""
        print("__le__ 被调用!")
        return self.score <= other.score

print(s1 <= s2)  # __le__ 被调用! -> True

__eq__:等于操作

作用

定义对象的"等于"逻辑,默认比较内存地址,但可以通过这个方法自定义。

触发场景

当你写下 a == b 时,Python会调用 a.__eq__(b)

示例

python 复制代码
class Student:
    ...
    def __eq__(self, other):
        """触发场景:s1 == s2"""
        print("__eq__ 被调用!")
        return self.score == other.score

print(s1 == s2)  # __eq__ 被调用! -> False

__ne__:不等于操作

作用

定义对象的"不等于"逻辑。

触发场景

当你写下 a != b 时,Python会调用 a.__ne__(b)

示例

python 复制代码
class Student:
    ...
    def __ne__(self, other):
        """触发场景:s1 != s2"""
        print("__ne__ 被调用!")
        return not self.__eq__(other)

print(s1 != s2)  # __ne__ 被调用! -> True

__gt__:大于操作

作用

定义对象的"大于"逻辑。

触发场景

当你写下 a > b 时,Python会调用 a.__gt__(b)

示例

python 复制代码
class Student:
    ...
    def __gt__(self, other):
        """触发场景:s1 > s2"""
        print("__gt__ 被调用!")
        return self.score > other.score

print(s1 > s2)  # __gt__ 被调用! -> False

__ge__:大于等于操作

作用

定义对象的"大于等于"逻辑。

触发场景

当你写下 a >= b 时,Python会调用 a.__ge__(b)

示例

python 复制代码
class Student:
    ...
    def __ge__(self, other):
        """触发场景:s1 >= s2"""
        print("__ge__ 被调用!")
        return self.score >= other.score

print(s1 >= s2)  # __ge__ 被调用! -> False

__hash__:哈希值计算

作用

定义对象的哈希值,用于集合操作(如 setdict)。

触发场景

当你调用 hash(a) 或将对象放入集合时,Python会调用 a.__hash__()

示例

python 复制代码
class Student:
    ...
    def __hash__(self):
        """触发场景:hash(s1) 或 s1 放入集合"""
        print("__hash__ 被调用!")
        return hash(self.score)

print(hash(s1))  # __hash__ 被调用!
students = {s1, s2}  # __hash__ 被调用!

"一键补齐比较运算符" 的装饰器

在 Python 中写一个可排序的类,需要实现 __eq____lt____le____gt____ge____ne__,样板代码量大且易错。

functools.total_ordering 就是官方给出的"懒癌"解决方案,它是一个 "一键补齐比较运算符" 的装饰器。

装饰器 @total_ordering自动生成缺失的比较方法

前提:你已提供 __eq__ 以及 __lt____le____gt____ge__ 中的任意 一个 。生成的代码逻辑严谨,避免手写 NotImplemented 处理。

使用方法

  1. 导入:from functools import total_ordering
  2. 装饰类:@total_ordering
  3. 实现 __eq__ 和一个顺序方法即可。

示例:学生成绩排序

python 复制代码
from functools import total_ordering

@total_ordering
class Student:
    def __init__(self, name, score):
        self.name, self.score = name, score

    def __eq__(self, other):
        return self.score == other.score

    def __lt__(self, other):
        return self.score < other.score

# 使用
alice, bob = Student('Alice', 90), Student('Bob', 85)
print(alice > bob)   # True
print(bob <= alice)  # True
print(sorted([bob, alice]))  # [Bob, Alice]

踩坑提示

  • 必须实现 __eq__,否则抛 ValueError
  • 不要混用 __cmp__(Python 3 已移除)。
  • 同时给出多个顺序方法时,装饰器以最左边为准。

实战:打造可比较、可排序的"分数"类

python 复制代码
from functools import total_ordering

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

    def __eq__(self, other):
        return self.value == other.value

    def __lt__(self, other):
        return self.value < other.value

    def __hash__(self):
        return hash(self.value)

    def __repr__(self):
        return f"Score({self.value})"

# 测试
s1 = Score(85)
s2 = Score(90)
s3 = Score(85)

print(s1 < s2)   # True
print(s1 == s3)  # True
print(s1 != s2)  # True
print(s1 > s2)   # False
print(s1 >= s3)  # True

scores = {s1, s2, s3}
print(scores)  # {Score(85), Score(90)}

sorted_scores = sorted([s1, s2, s3])
print(sorted_scores)  # [Score(85), Score(90)]

小结

  • 比较运算魔术方法 让对象支持 < <= == != > >= 比较。
  • __hash__ 是集合操作的关键,必须与 __eq__ 保持一致。
  • 使用 functools.total_ordering 可以简化比较方法的实现。

动手挑战

    1. 实现一个 Person 类,支持按年龄比较大小,并且可以放入集合。
    1. 创建一个 Book 类,支持按书名排序,并且可以通过 hash() 获取哈希值。
    1. 进阶:让 Book 类支持按书名和作者同时比较大小。

互动时间

你最常用哪个比较魔术方法?

A. __eq__(比较狂魔)

B. __lt__(排序狂魔)

C. __hash__(集合狂魔)

评论区告诉我你的答案 + 骚操作!

最后感谢阅读!欢迎关注我,微信公众号倔强青铜三

一键三连(点赞、收藏、关注)!

相关推荐
牧羊人.33310 小时前
动手学深度学习 03 | 卷积神经网络实现手写数字识别
人工智能·深度学习·神经网络·算法·cnn
VL——MOESR10 小时前
【具身智能】Cosmos Policy论文阅读随笔
论文阅读·人工智能·机器学习·具身智能·cosmospolicy
北京晶数信息科技10 小时前
加油机数据采集设备加油机数据采集器加油机智能采集器液位仪数据采集设备原厂成品油流通数智化综合监管平台技术原理与落地应用解决方案
大数据·人工智能·物联网·需求分析
NineData10 小时前
NineData智能数据管理平台新功能发布|2026年8月
数据库·人工智能·oracle·中间件·agent·数据库开发·ninedata
凌风的跨境分享10 小时前
Temu店群运维提效:定时策略自动化任务全场景实操指南
大数据·运维·前端·人工智能·架构·自动化
又見山10 小时前
Codex 实战:用 AI 写运维脚本
运维·人工智能
Jazz_z10 小时前
纯 Python 环境下 Excel 文件的读取与导入详解
python
海带紫菜菠萝汤11 小时前
开源大模型出海开始收费:许可证里的三条路线与真实影响
人工智能·ai·开源·大模型
A hao11 小时前
LED视频处理器中帧率与刷新率的区别
大数据·图像处理·人工智能·音视频
AgentMaster11 小时前
数据治理工具选型指南:一套可复用的四阶段决策框架
大数据·数据结构·人工智能·算法