Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you override a magic method when extending a builtin in python?

Tags:

python

I am trying to extend a str and override the magic method __cmp__. The below example shows that the magic method __cmp__ is never called when > is used:

class MyStr(str):
    def __cmp__(self, other):
        print '(was called)',
        return int(self).__cmp__(int(other))


print 'Testing that MyStr(16) > MyStr(7)'
print '---------------------------------'
print 'using _cmp__ :', MyStr(16).__cmp__(MyStr(7))
print 'using > :', MyStr(16) > MyStr(7)

when run results in:

Testing that MyStr(16) > MyStr(7)
---------------------------------
using __cmp__ : (was called) 1
using > : False

Obviously, when using the > the underlying "compare" functionality within the builtin is getting called, which in this case is an alphabetization ordering.

Is there a way to override the __cmp__ builtin with magic methods? And if you cannot directly - what is going on here that is different than non-magic methods where you can?

like image 896
Rocketman Avatar asked Oct 05 '22 21:10

Rocketman


1 Answers

Comparison operators do not call __cmp__ if the corresponding magic method or its counterpart are defined and do not return NotImplemented:

class MyStr(str):
    def __gt__(self, other):
        print '(was called)',
        return int(self) > int(other)


print MyStr(16) > MyStr(7)   # True

 

P.S.: You probably don't want harmless comparisons to throw exceptions:

class MyStr(str):
    def __gt__(self, other):
        try:
            return int(self) > int(other)
        except ValueError:
            return False
like image 124
Pavel Anossov Avatar answered Oct 10 '22 02:10

Pavel Anossov