理解python和递归中的cmp

理解python和递归中的cmp,python,python-2.7,Python,Python 2.7,我正在使用一些现有代码(通过\uu\cmp\uu方法)为类重新定义相等性。它没有像预期的那样工作,在试图修复它的过程中,我遇到了一些我不理解的行为。如果您在一个只调用内置函数cmp的类上定义\uumcmp,那么我希望它总是达到最大递归深度。但是,如果尝试将类的实例与自身进行比较,则返回0 代码如下: class A: def __cmp__(self, other): return cmp(self, other) a = A() b = A() cmp(a, a) #

我正在使用一些现有代码(通过
\uu\cmp\uu
方法)为类重新定义相等性。它没有像预期的那样工作,在试图修复它的过程中,我遇到了一些我不理解的行为。如果您在一个只调用内置函数
cmp
的类上定义
\uumcmp
,那么我希望它总是达到最大递归深度。但是,如果尝试将类的实例与自身进行比较,则返回0

代码如下:

class A:
    def __cmp__(self, other):
        return cmp(self, other)

a = A()
b = A()
cmp(a, a) # returns 0
cmp(b, b) # returns 0
cmp(a, b) # results in RuntimeError: maximum recursion depth exceeded
我理解运行时错误,但我不理解为什么对
cmp
的前两个调用成功

我已经阅读了python文档的一节和其他类似的内容,但是找不到这个递归的答案


是的,我明白,正如我写的,这是一个毫无意义的类。我正在使用的代码试图在某些情况下重新定义平等性,否则就会陷入基本情况。basecase不能像实现的那样工作,所以我正在尝试修复它。我认为调用
cmp
可能会起作用,并发现了这个问题。我希望理解这一点能帮助我找到合适的解决方案。

如果两个名称引用同一个对象,它们在定义上是相等的(edit:至少就
cmp
而言,“equal”实际上意味着“既不大于也不小于”).

因为
cmp
的语义要求被比较的对象具有排序关系(即,在
cmp(x,y)
调用中,以下恰好一项是正确的:
x
x==y
x>y
),
cmp
可以假设一个参数等于它本身,如果参数是同一个对象,则跳过对任何比较方法的调用


(Python中的很多东西都假设对于任何对象,
x
x==x
。这有时会导致错误(特别是对于NaN浮点值),但大多数情况下,这是一个有用的优化。在
cmp
的情况下,这很好,因为
cmp
需要
x==x
作为
cmp(x,x)的先决条件)

cmp(a,a)
正在调用内置的
cmp
。如果不查看源代码,我猜
self is other
检查是在不调用类
\uuuuu cmp\uuuu
的情况下进行的。如果两个对象不相同,则调用
\uu\cmp\uu

不一定
float('nan')
不等于它本身。@user2357112:这里有一条关于
cmp
nan
的行为的线索:我恐怕没有时间读它的结论。:-)正如Tim Peters所说,“cmp(x,y)对于只有偏序的对象没有意义,所以我不关心cmp()对NaN做了什么。”好的,我根据这个答案做了更多的测试。看起来
cmp(a,a)
甚至都没有调用
\uuu cmp\uuu
方法。它只是返回0的快捷方式。这意味着
cmp(x,x)
并不总是与
x相同。有些混乱,但可以理解。我尝试了相同的代码,但没有得到任何结果error@AswinMurugesh-您使用的是什么版本的Python?我使用的是2.7.3(如果你疯了的话)可以这样定义相等:
x==x
False
,但是
cmp(x,x)
仍然返回0。但是你要说的是,
cmp
假设你没有那么疯狂。@ChrisPalmer:正如user2357112所指出的,
NaN
就是这样。当然,NaN是个疯子,所以没关系。:-)