Understanding cmp in python and recursion

I am working with some existing code that overrides equality (using the __cmp__ method) for a class. It does not work as expected, and trying to fix it, I came across some kind of behavior that I do not understand. If you define __cmp__ for a class that just calls the cmp built-in function, I would expect it to always reach maximum recursion depth. However, if you try to compare an instance of a class with itself, it returns 0.

Here is the code:

 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 I understand, but I do not understand why the first two cmp calls succeed.

I read the data model section in python docs and other things like this nice python partitioning equality , but cannot find the answer to this recursion.

And, yes, I understand that, as written, this is a completely meaningless class. The code I'm working with is trying to redefine equality in certain situations and otherwise gets into the base base. The base database does not work as it is implemented, and therefore I am trying to fix it. I thought the cmp call might work and found this problem. I hope that understanding this will help me find a suitable solution.

+4
source share
3 answers

If two names refer to the same object, they are by definition equal to ( edit ): at least until cmp , where "equal" really means "neither more nor less").

+1
source

Since the semantics of cmp requires that the objects being compared have an ordering relationship (i.e., in a call to cmp(x, y) one of the following is true: x < y , x == y or x > y ), cmp may assume that the argument is to itself and misses calls to any comparison methods if the arguments are the same object.

(Many things in Python assume that for any object x , x == x . This sometimes causes errors (especially with NaN floating point values), but most of the time it is a useful optimization. Case cmp , this is fine, since cmp requires x == x as a prerequisite for cmp(x, x) .)

+1
source

cmp(a,a) calls the built-in cmp . Despite the source, I assume that the self is other check self is other performed without calling the __cmp__ class. If both objects are not identical, __cmp__ is __cmp__ .

0
source

Source: https://habr.com/ru/post/1494994/


All Articles