Python, How to extend Decimal class to add helpful methods -
i extend decimal class add helpful methods it, specially handling money.
the problem when go this:
from decimal import decimal class newdecimal(decimal): def new_str(self): return "${}".format(self) d1 = newdecimal(1) print d1.new_str() # prints '$1' d2 = newdecimal(2) d3 = newdecimal(3) d5 = d2 + d3 print d5.new_str() #exception happens here
it throws exception:
attributeerror: 'decimal' object has no attribute 'new_str'
this because of way decimal arithmetic, returns new decimal object, literally calling decimal(new value) @ end of computation.
no workaround other reimplementing arithmetic?
you don't want have method printing decimal objects in alternate way. top-level function or monkeypatched method whole lot simpler, , cleaner. or, alternatively, money
class has decimal
member delegates arithmetic to.
but want doable.
to make newdecimal(1) + newdecimal(2)
return newdecimal(3)
, can override __add__
:
def __add__(self, rhs): return newdecimal(super().__add__(rhs))
and of course you'll want override __iadd__
well. , don't forget mul
, other numeric special methods.
but still won't decimal(2) + newdecimal(3)
. make work, need define newdecimal.__radd__
. need ensure newdecimal.__radd__
called instead of decimal.__add__
, when you're using inheritance, that's easy, because python has rule make easy:
note: if right operand’s type subclass of left operand’s type , subclass provides reflected method operation, method called before left operand’s non-reflected method. behavior allows subclasses override ancestors’ operations.
you may want read section implementing arithmetic operations in numbers
module docs, , the implementation of fractions.fraction
(which intended serve sample code creating new numeric types, why docs link directly source). life easier fraction
's because can fall decimal
every operation , convert (since newdecimal
doesn't have different numeric behavior decimal
), it's worth seeing issues, , understanding ones , aren't relevant , why.
Comments
Post a Comment