python - __lt__而不是__cmp__

Python 2.x有两种方法可以重载比较运算符,__cmp__或者#34;丰富的比较运算符" 例如__cmp__。据说富裕的比较超载是首选,但为什么会这样呢?

丰富的比较运算符更容易实现每个,但您必须使用几乎相同的逻辑实现其中几个。 但是,如果你可以使用内置的__cmp__和元组排序,那么<=变得非常简单并完成所有的比较:

class A(object):

def __init__(self, name, age, other):

self.name = name

self.age = age

self.other = other

def __cmp__(self, other):

assert isinstance(other, A) # assumption for this example

return cmp((self.name, self.age, self.other),

(other.name, other.age, other.other))

这种简单性似乎比重载所有6(!)丰富的比较更好地满足了我的需求。 (但是,如果依靠&#34;交换的参数&#34; /反映的行为,你可以把它归结为&#34; 4,但这导致并发症的净增加,在我的拙见中。)

如果我只是超载__cmp__,是否有任何不可预见的陷阱需要注意?

我理解__cmp__,<=,==等操作符可以为其他目的而重载,并且可以返回他们喜欢的任何对象。 我并不是在询问这种方法的优点,而是仅仅考虑使用这些算子进行比较时的差异,这与他们对数字的意义相同。

更新:正如克里斯托弗指出的那样,__cmp__正在消失3.x. 是否有任何替代方案可以使实施比较像上面的__cmp__一样简单?

5个解决方案

84 votes

是的,很容易实现所有内容,例如: __key__有一个mixin类(或者一个元类,或者一个类装饰器,如果你的味道以这种方式运行)。

例如:

class ComparableMixin:

def __eq__(self, other):

return not self

def __ne__(self, other):

return self

def __gt__(self, other):

return other

def __ge__(self, other):

return not self

def __le__(self, other):

return not other

现在你的类只能定义__key__并从ComparableMixin中多次继承(在需要其他任何基础之后,如果有的话)。 类装饰器非常相似,只是插入类似的函数作为它所装饰的新类的属性(结果可能在运行时在显微镜下更快,在内存方面同样是微小的成本)。

当然,如果你的班级有一些特别快速的实施方式(例如)__key__和__cmp__,它应该直接定义它们以便不使用mixin的版本(例如,__lt__的情况) - 在 事实__ne__可能被定义为促进这一点:

def __ne__(self, other):

return not self == other

但在上面的代码中,我想保持令人愉悦的对称性,只使用__key__ ;-)。至于为什么__cmp__必须去,因为我们确实有__lt__和朋友,为什么要保持另一种不同的方式来做同样的事情呢? 它在每个Python运行时(Classic,Jython,IronPython,PyPy,......)中都非常重要。 肯定不会有错误的代码就是那些不存在的代码 - 而Python的原则应该是理想情况下执行任务的一种明显方式(C具有相同的原则) &#34; ISO标准的C&#34;部分,btw)。

这并不意味着我们会竭尽全力禁止某些事情(例如,某些用途的mixins和类装饰器之间的近似等价),但这肯定意味着我们不想随身携带代码 冗余存在的编译器和/或运行时只是为了支持多个等效方法来执行完全相同的任务。

进一步编辑:实际上有一种更好的方法可以为许多类提供比较和散列,包括问题中的方法 - 一种__key__方法,正如我在对问题的评论中提到的那样。 因为我从来没有为它编写PEP,所以如果你喜欢的话,你现在必须使用Mixin(&amp; c)来实现它:

class KeyedMixin:

def __lt__(self, other):

return self.__key__() < other.__key__()

# and so on for other comparators, as above, plus:

def __hash__(self):

return hash(self.__key__())

对于实例与其他实例的比较来说,将每个元组的元组与几个字段进行比较,这是一个非常常见的情况 - 然后,散列应该在完全相同的基础上实现。 __key__特殊方法直接解决了这个问题。

Alex Martelli answered 2019-08-14T04:12:29Z

44 votes

为了简化这种情况,Python 2.7 + / 3.2 +中的类装饰器,functools.total_ordering,可用于实现Alex建议的内容。 来自文档的示例:

@total_ordering

class Student:

def __eq__(self, other):

return ((self.lastname.lower(), self.firstname.lower()) ==

(other.lastname.lower(), other.firstname.lower()))

def __lt__(self, other):

return ((self.lastname.lower(), self.firstname.lower()) <

(other.lastname.lower(), other.firstname.lower()))

jmagnusson answered 2019-08-14T04:12:55Z

9 votes

这由PEP 207 - Rich Comparisons涵盖

此外,__cmp__在python 3.0中消失了。 (请注意,它不在[http://docs.python.org/3.0/reference/datamodel.html]上,但它位于[http://docs.python.org/2.7/reference/datamodel.html])

Christopher answered 2019-08-14T04:13:29Z

0 votes

灵感来自Alex Martelli的ComparableMixin&amp; KeyedMixin答案,我想出了以下mixin。它允许您实现单个_compare_to()方法,该方法使用基于密钥的比较类似于KeyedMixin,但允许您的类根据other的类型选择最有效的比较密钥。(请注意,这个mixin对于可以测试相等而不是顺序的对象没有多大帮助)。

class ComparableMixin(object):

"""mixin which implements rich comparison operators in terms of a single _compare_to() helper"""

def _compare_to(self, other):

"""return keys to compare self to other.

if self and other are comparable, this function

should return ``(self key, other key)``.

if they aren't, it should return ``None`` instead.

"""

raise NotImplementedError("_compare_to() must be implemented by subclass")

def __eq__(self, other):

keys = self._compare_to(other)

return keys[0] == keys[1] if keys else NotImplemented

def __ne__(self, other):

return not self == other

def __lt__(self, other):

keys = self._compare_to(other)

return keys[0] < keys[1] if keys else NotImplemented

def __le__(self, other):

keys = self._compare_to(other)

return keys[0] <= keys[1] if keys else NotImplemented

def __gt__(self, other):

keys = self._compare_to(other)

return keys[0] > keys[1] if keys else NotImplemented

def __ge__(self, other):

keys = self._compare_to(other)

return keys[0] >= keys[1] if keys else NotImplemented

Eli Collins answered 2019-08-14T04:13:58Z

0 votes

(17/17/17编辑,以考虑评论。)

我在上面尝试了类似的mixin答案。 我和#34;无&#34;遇到了麻烦。 这是一个修改版本,处理与&#34;无&#34;的相等比较。 (我没有理由因为缺乏语义而无法与None进行不等式比较):

class ComparableMixin(object):

def __eq__(self, other):

if not isinstance(other, type(self)):

return NotImplemented

else:

return not self

def __ne__(self, other):

return not __eq__(self, other)

def __gt__(self, other):

if not isinstance(other, type(self)):

return NotImplemented

else:

return other

def __ge__(self, other):

if not isinstance(other, type(self)):

return NotImplemented

else:

return not self

def __le__(self, other):

if not isinstance(other, type(self)):

return NotImplemented

else:

return not other

Gabriel Ferrer answered 2019-08-14T04:14:32Z

resoult在python啥意思,python - __lt__而不是__cmp__相关推荐

  1. python基础类型,Python基础-类

    Python基础-类 @(Python)[python, python基础] 写在前面 如非特别说明,下文均基于Python3 摘要 本文重点讲述如何创建和使用Python类,绑定方法与非绑定方法的区 ...

  2. python学习手册-Python学习手册

    Python学习手册第4 版将帮助你使用Python快速实现这一点,不管你是编程新手还是Python初学者.本书是易于掌握和自学的教程,根据作者Python专家Mark Lutz的著名培训课程编写而成 ...

  3. Python Code Examples Python代码示例!

    Python is a general purpose programming language which is dynamically typed, interpreted, and known ...

  4. 已知x=python是一种非常好的编程语言-为什么用Python,高级的Python是一种高级编程语言...

    Python特性 如果有人问我Python最大的特点是什么,我会毫不犹豫地告诉他:它简单易学,功能强大.作为一个纯自由软件,Python有许多优点: 很简单.基于"优雅".&quo ...

  5. python编程语言创始人-Python简史:开发者的小小副业如何成为全球最热编程语言?...

    原标题:Python简史:开发者的小小副业如何成为全球最热编程语言? 选自TechRepublic 作者:Nick Heath 机器之心编译 参与:魔王.张倩.杜伟 1989 年,Guido van ...

  6. python笔记基础-python基础学习笔记(一)

    安装与运行交互式解释器 在绝大多数linux和 UNIX系统安装中(包括Mac OS X),Python的解释器就已经存在了.我们可以在提示符下输入python命令进行验证(作者环境ubuntu) f ...

  7. python笔记基础-python学习笔记(一)python简介和基础

    1.什么是python? python是一种面向对象的,解释型的计算机语言,它的特点是语法简介,优雅,简单易学.1989年诞生,Guido(龟叔)开发. 编译型语言:代码在编译之后,编译成2进制的文件 ...

  8. python快速编程入门教程-半小时带你快速入门Python编程,Python快速入门教程

    1,Introduction to Python (Python入门) 2,Python是什么? Python 官方网站的描述 Python is a programming language tha ...

  9. python代码块-python代码块

    广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. 开发准备cas 的 python sdk 包含了用于访问和操作 cas ...

最新文章

  1. 005-Python之列表,元组,字符串,bytes及bytearray共有操作
  2. Elasticsearch入门之从零开始安装ik分词器
  3. 技术支持工程师自测评估下载
  4. 《我的青春谁做主》我想要的结局
  5. mathematica练习程序(图像取反)
  6. 电力笔记-30个行业专业词汇(Ⅰ期)
  7. 微软Power BI报表服务器学习总览
  8. C语言 用传统流程图表示分段函数,C语言程序设计习题答案
  9. 线性表的顺序存储结构--数组(顺序表)、栈、队列
  10. c# 匿名用戶登錄以後的事件處理
  11. 高等数学(第七版)同济大学 习题1-10 个人解答
  12. Android 7.0应用冷启动流程分析
  13. 【数据结构】以不完整拼音搜索通讯录算法设计
  14. C# 操作Word页眉页脚——奇偶页/首页不同、不连续设置页码、复制页眉页脚、锁定页眉页脚、删除页眉页脚...
  15. linux下重要目录的作用
  16. 想想也有五年多了(胡紫薇博客)
  17. 你距离女朋友其实只差一个幽默的句子,python教你如何快速将有趣的句子收归数据库
  18. PostgreSQL 修改密码
  19. MYSQL 按名字分组查询最好成绩
  20. 怎么把dell 灵越2020一体机的win8系统改成win7?

热门文章

  1. yum与rpm的使用
  2. java月份去0_java – 使用月份解析日期而不是前导0
  3. erwin模型怎么保存_一行命令启动,十分钟内完成部署,Paddle Serving开放模型即服务功能...
  4. 【温故知新】HTML学习笔记(上)
  5. 【PM模块】维护订单基本处理流程——实际操作
  6. SAP ABAP开发实用快捷键
  7. 定义工厂(Plant)
  8. MIR6校验时移动平均价为负的原因及解决
  9. SAP中如何实现<生产订单>的批量删除方法!
  10. 更新Oracle的Date字段