理解python和递归中的cmp

时间:2013-08-02 16:31:33

标签: python python-2.7

我正在使用一些现有的代码来重新定义类的相等性(通过__cmp__方法)。它没有按预期工作,并试图修复它我遇到了一些我不明白的行为。如果你在一个只调用内置函数__cmp__的类上定义cmp,那么我希望它总能达到最大递归深度。但是,如果您尝试将类的实例与自身进行比较,则返回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

我理解RuntimeError,但我不明白为什么前两次调用cmp成功。

我已经阅读了python文档的data model部分以及其他类似python equality的细分,但无法找到此递归的答案。

而且,是的,我理解,这是一个完全没有意义的课程。我正在使用的代码试图在某些情况下重新定义相等性,否则会陷入基础。 basecase不能实现,所以我试图解决它。我认为调用cmp可能有效,并发现了这个问题。我希望理解这一点有助于我找到合适的解决方案。

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

由于cmp的语义要求被比较的对象具有排序关系(即在cmp(x, y)调用中恰好满足下列条件之一:x < y,{{1} },或x == y),x > y可以假设参数等于自身,并且如果参数是同一个对象,则跳过对任何比较方法的调用。

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

答案 2 :(得分:0)

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