How can i change the __cmp__ function of an instance (not in class)?
Ex:
class foo:
def __init__(self, num):
self.num = num
def cmp(self, other):
return self.num - other.num
# Change __cmp__ function in class works
foo.__cmp__ = cmp
a = foo(1)
b = foo(1)
# returns True
a == b
# Change __cmp__ function in instance that way doesnt work
def cmp2(self, other):
return -1
a.__cmp__ = cmp2
b.__cmp__ = cmp2
# Raise error
a == b
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
#TypeError: cmp2() takes exactly 2 arguments (1 given)
It will make your code buggy and hard to maintain. The reason it is difficult is because the right way to do it is to subclass foo
:
class FunkyCmpFoo( foo ):
def __cmp__( self, other ):
return -1
&c., &c. This way, you know that all foo
s compare in the same way, and all FunkyCmpFoo
s compare in the same way. If you don't, you will eventually end up comparing a modified foo
with an original foo
, and Cthulhu himself will rise from the depths to punish you.
I'm not sure whether I should say this, but it is possible, by creating your own instance methods:
funcType = type( foo.__cmp__ )
# Alternatively:
import new
cmp2 = new.instancemethod( func, a, foo )
a.__cmp__ = funcType( cmp2, a, foo )
b.__cmp__ = funcType( cmp2, b, foo )
I can think of one good reason to do this, and that is if your archenemy has to debug the code. In fact, I can think of some quite fun things to do with that in mind (how would you like sys.maxint
to compare less than all even numbers?). Apart from that, it's a nightmare.
Edit: This is the part where I'm supposed to say you're a bad person if you do this in production code. All your hair and teeth will fall out, and you'll be cursed to walk the stack forever during your afterlife.
Add an extra bit of indirection so you're not mixing up bound/unbound methods:
class foo(object):
def __init__(self, num):
self.num = num
self.comparer = self._cmp
def __cmp__(self, other):
return self.comparer(self, other)
@staticmethod
def _cmp(this, that):
print 'in foo._cmp'
return id(this) == id(that)
def setcmp(self, f):
self.comparer = f
def cmp2(self, other):
print 'in cmp2'
return -1
a = foo(1)
b = foo(1)
print a == b
a.setcmp(cmp2)
b.setcmp(cmp2)
print a == b
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With