I'm creating a Money class, and I'd like to pass the object directly to the string format() function and get the money representation with 2 decimals and the currency symbol.
What method should I override to print with the string format function? Overriding str and repr did not work.
from decimal import Decimal
class Money(Decimal):
    def __str__(self):
        return "$" + format(self, ',.2f')
    def __repr__(self):
        return "$" + format(self, ',.2f')
m = Money("123.44")
print(m) # $123.44. Good.
m        # $123.44. Good.
print("Amount: {0}".format(m)) # 123.44. Bad. I wanted $123.44
print(f"Amount: {m}") # 123.44. Bad. I wanted $123.44
                You can give your class a __format__ method; in this case just call overridden version:
def __format__(self, spec):
    spec = spec or ',.2f'  # set a default spec when not explicitly given
    return '$' + super().__format__(spec)
From the linked documentation:
Called by the
format()built-in function, and by extension, evaluation of formatted string literals and thestr.format()method, to produce a “formatted” string representation of an object. Theformat_specargument is a string that contains a description of the formatting options desired. The interpretation of theformat_specargument is up to the type implementing__format__(), however most classes will either delegate formatting to one of the built-in types, or use a similar formatting option syntax.
You'll want to drop your __str__ and __repr__ implementations now, or at least not add another '$' on top of the one __format__ now adds (which format(self, ...) will trigger).
Demo:
>>> from decimal import Decimal
>>> class Money(Decimal):
...     def __format__(self, spec):
...         spec = spec or ',.2f'  # set a default spec when not explicitly given
...         return '$' + super().__format__(spec)
...
>>> m = Money("123.44")
>>> print("Amount: {0}".format(m))
Amount: $123.44
>>> print(f"Amount: {m}")
Amount: $123.44
                        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