Python, How to extend Decimal class to add helpful methods
Question: I would like to extend the Decimal class to add some helpful methods to it,
specially for handling money.

The problem when I go do 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 an exception:

    
    
    AttributeError: 'Decimal' object has no attribute 'new_str'
    

This is because of the way Decimal does arithmetic, it always returns a new
Decimal object, by literally calling Decimal(_new value_) at the end of the
computation.  
Does anyone no a workaround for this other than completely reimplementing all
the arithmetic?


Answer: You probably don't actually want to do this just to have an extra method for
printing Decimal objects in an alternate way. A top-level function or
monkeypatched method is a whole lot simpler, and cleaner. Or, alternatively, a
`Money` class that has a `Decimal` member that it delegates arithmetic to.

But what you want is doable.

* * *

To make `NewDecimal(1) + NewDecimal(2)` return `NewDecimal(3)`, you can just
override `__add__`:

    
    
    def __add__(self, rhs):
        return NewDecimal(super().__add__(rhs))
    

And of course you'll want to override `__iadd__` as well. And don't forget
`mul` and all the other [numeric special
methods](http://docs.python.org/3.3/reference/datamodel.html#emulating-
numeric-types).

But that still won't help for `Decimal(2) + NewDecimal(3)`. To make that work,
you need to define `NewDecimal.__radd__`. You also need to ensure that
`NewDecimal.__radd__` will get called instead of `Decimal.__add__`, but when
you're using inheritance, that's easy, because Python has a rule specifically
to make this easy:

> _Note:_ If the right operand’s type is a subclass of the left operand’s type
> and that subclass provides the reflected method for the operation, this
> method will be called before the left operand’s non-reflected method. This
> behavior allows subclasses to override their ancestors’ operations.

* * *

You may want to read the section [Implementing the arithmetic
operations](http://docs.python.org/3/library/numbers.html#implementing-the-
arithmetic-operations) in the `numbers` module docs, and [the implementation
of
`fractions.Fraction`](http://hg.python.org/cpython/file/3.3/Lib/fractions.py)
(which was intended to serve as sample code for creating new numeric types,
which is why the docs link directly to the source). Your life is easier than
`Fraction`'s because you can effectively fall back to `Decimal` for every
operation and then convert (since `NewDecimal` doesn't have any different
numeric behavior from `Decimal`), but it's worth seeing all the issues, and
understanding which ones are and aren't relevant and why.

