In my effort to subclass float
and override multiple numeric operations with a wrapper, I looked at this example and tried the following:
def naturalize(*methods):
def decorate(cls):
for method in methods:
method = '__' + method + '__'
original = getattr(cls.__base__, method)
setattr(cls, method, lambda self, *args, **kwargs: cls(original(self, *args, **kwargs)))
return cls
return decorate
@naturalize('add', 'sub', 'mul')
class P(float):
pass
print('Test result:', P(.1) + .2, P(.1) - .2, P(.1) * .2)
# Test result: 0.020000000000000004 0.020000000000000004 0.020000000000000004
This didn't work: __add__
, __sub__
and __mul__
were all working like __mul__
. So I looked at this other example and tried:
def naturalize(*methods):
def decorate(cls):
def native(method):
original = getattr(cls.__base__, method)
return lambda self, *args, **kwargs: cls(original(self, *args, **kwargs))
for method in methods:
method = '__' + method + '__'
setattr(cls, method, native(method))
return cls
return decorate
@naturalize('add', 'sub', 'mul')
class P(float):
pass
print('Test result:', P(.1) + .2, P(.1) - .2, P(.1) * .2)
#Test result: 0.30000000000000004 -0.1 0.020000000000000004
Now, that did work. But I'm still not sure what exactly went wrong with my first approach. Can anyone please explain to me how exactly __add__
, __sub__
and __mul__
ended up all working like __mul__
?