Python对象比较与排序_魔术方法解析【教程】
技术百科
舞姬之光
发布时间:2026-01-01
浏览: 次 Python对象比较排序依赖魔术方法;需正确实现__eq__与__hash__一致性,避免修改状态,复杂对象优先用dataclass(order=True)自动生成。
Python中对象的比较和排序依赖于特定的魔术方法,正确实现这些方法能让自定义类支持==、、sorted()等操作,避免TypeError或逻辑错误。
__eq__ 与相等性判断
当使用==比较两个对象时,Python会调用__eq__方法。默认行为是基于对象身份(is),即不同实例即使属性相同也返回False。要按内容判断相等,需显式实现__eq__,并通常同时实现__hash__(若需放入集合或作为字典键)。
- 推荐在
__eq__中先检查类型:if not isinstance(other, type(self)): return False - 返回
True或False,不要返回其他值,否则可能引发意外行为 - 若重写了
__eq__但未定义__hash__,实例将自动变为不可哈希(hash(obj)报错)
__lt__、__le__ 等富比较方法
Python 3 中取消了__cmp__,改用六个富比较方法:__lt__(__le__(__eq__(==)、__ne__(!=)、__gt__(>)、__ge__(>=)。只要实现了其中一部分,其余可通过functools.total_ordering自动补全。
- 装饰类时只需实现
__eq__和一个如__lt__,其余比较逻辑自动推导 -
total_ordering不会覆盖已定义的方法,适合渐进式补充 - 注意:仅当所有比较都基于同一组属性时才适用,混合逻辑可能导致不一致
__lt__ 是排序的关键入口
sorted()、list.sort()等默认按升序排列,其底层调用的是对象的__lt__方法。只要类实现了__lt__(或通过total_ordering间接支持),就能直接参与排序。
- 例如:
sorted([obj1, obj2, obj3])会反复调用obj1.__lt__(obj2)等进行两两比较 - 若未实现
__lt__,会抛出TypeError: ' - 也可传入
key参数绕过魔术方法,如sorted(items, key=lambda x: x.score)
常见陷阱与建议
忽略魔术方法的对称性或一致性,容易导致逻辑混乱。比如a == b为True,但hash(a) != hash(b)会使字典行为异常;又或a 和b > a结果不一致,影响排序稳定性。
- 实现
__eq__时,确保相等对象的__hash__返回相同整数(若可哈希) - 避免在比较方法中修改对象状态,这违反纯函数预期,可能引发难以调试的问题
- 对于复杂对象,优先考虑用
dataclass(orde自动生成比较方法,简洁且不易出错
r=True)
# python
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- MySQL 中使用 IF 和 CASE 实现查询字
- Mac如何备份到iCloud_Mac桌面与文稿文件
- Python对象生命周期管理_创建销毁说明【指导】
- 如何高效删除 NumPy 二维数组中所有元素相同的
- 为什么本地php环境运行php脚本卡顿_php执行
- Win11如何卸载OneDrive_Win11卸载
- Win11键盘快捷键大全_Windows 11常用
- 如何用::实现单例模式_php静态方法与作用域操作
- Windows怎样关闭锁屏广告_Windows关闭
- Python包结构设计_大型项目组织解析【指导】
- C#怎么使用委托和事件 C# delegate与e
- c++ stringstream用法详解_c++字
- php错误怎么开启_display_errors与
- Win11怎么更改系统语言为中文_Windows1
- Python异步网络编程_aiohttp说明【指导
- 使用类变量定义字符串常量时的类型安全最佳实践
- Win11怎么设置虚拟内存最佳大小_Windows
- 如何用正则表达式精确匹配“start”到“end”
- Win11怎么打开旧版计算器_Win11恢复传统计
- 如何在 Go 中创建包含映射(map)的切片(sl
- Windows10系统怎么查看IP地址_Win10
- Win11怎么关闭系统透明度_Windows11个
- Win11怎么关闭定位服务 Win11禁止应用获取
- Win11怎么把图标拖到任务栏_Win11固定应用
- Win11如何设置电源计划_Win11电源计划优化
- Windows的便笺功能如何使用?(桌面备忘技巧)
- 如何在Golang中优化文件读写性能_使用缓冲和并
- c++中如何使用auto关键字_c++11类型推导
- Django 测试数据库表缺失与字段未创建问题的完
- Windows10如何更改系统字体大小_Win10
- Win11怎么设置屏保时间_调整Win11屏幕保护
- 如何在Golang中使用encoding/gob序
- php本地部署后数据库连接报错_1045acces
- 如何在Golang中处理云原生事件_使用Event
- Win11如何设置计划任务 Win11定时执行程序
- Python与MongoDB NoSQL开发实战_
- 如何使用Golang实现错误包装与传递_Golan
- Windows电脑如何截屏?(四种快捷方法)
- Mac电脑进水了怎么办_MacBook进水后紧急处
- WindowsUSB驱动安装异常怎么办_USB驱动
- Ajax提交表单PHP怎么接收_处理Ajax发送的
- c++获取当前时间戳_c++ time函数使用详解
- Win11怎么设置ip地址_Windows 11手
- Win10如何卸载自带Edge_Win10彻底卸载
- Windows10如何更改任务栏高度_Win10解
- C++如何使用std::optional?(处理可
- Win11怎么关闭触摸键盘图标_Windows11
- Windows10电脑怎么设置文件权限_Win10
- Win10任务栏天气和资讯怎么关闭 Win10禁用
- php查询数据怎么导出csv_查询结果转csv文件

r=True)
QQ客服