Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing original int comparison from int-derived class with overloaded comparison operator

I have an int-derived class with overloaded comparison operator.

In the body of the overloaded methods I need to use the original operator.

The toy example:

>>> class Derived(int):
...     def __eq__(self, other):
...         return super(Derived, self).__eq__(other)

works fine with Python 3.3+, but fails with Python 2.7 with exception AttributeError: 'super' object has no attribute '__eq__'.

I can think about several walkarrounds, which I found not very clean:

return int(self) == other

requires creation of a new int object just to compare it, while

try:
    return super(Derived, self).__eq__(other)
except AttributeError:
    return super(Derived, self).__cmp__(other) == 0

splits the control flow based on the Python version, which I find terribly messy (so is inspecting the Python version explicitly).

How can I access the original integer comparison in an elegant way working with Python 2.7 and 3.3+?

like image 210
abukaj Avatar asked Oct 17 '22 21:10

abukaj


2 Answers

Python 2 and 3 are significantly different from each other so I think you should bite the bullet and check versions. That is only to be expected if you're trying to write code that works on both (sooner or later in my experience you find something you have to patch). To avoid any performance impact you could do something like:

from six import PY2

class Derived(int):
    if PY2:
        def __eq__(self, other):
            return super(Derived, self).__cmp__(other) == 0
    else:
        def __eq__(self, other):
            return super(Derived, self).__eq__(other)

That's what I'd do. If I really wanted to subclass int...

If you really don't want to, perhaps you could try:

class Derived(int):
    def __eq__(self, other):
        return (self ^ other) == 0

Obviously if you care about performance you'll have to do some profiling with the rest of your code and find out if either of them is significantly worse...

like image 54
daphtdazz Avatar answered Oct 21 '22 08:10

daphtdazz


Both versions implement an __xor__ method, you could try this:

class Derived(int):
    def __eq__(self, other):
        return not super(Derived, self).__xor__(other)
like image 43
joebeeson Avatar answered Oct 21 '22 07:10

joebeeson