理解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是个疯子,所以没关系。:-)