如何使用字符串格式函数打印对象的表示形式?

How to print an object's representation using the string format function?

我正在创建一个 Money class,我想将该对象直接传递给字符串 format() 函数并获得带有 2 位小数和货币符号的货币表示形式。

我应该重写什么方法来打印字符串格式化函数?覆盖 strrepr 无效。

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) # 3.44. Good.
m        # 3.44. Good.
print("Amount: {0}".format(m)) # 123.44. Bad. I wanted 3.44
print(f"Amount: {m}") # 123.44. Bad. I wanted 3.44

你可以给你的class一个__format__ method;在这种情况下,只需调用覆盖版本:

def __format__(self, spec):
    spec = spec or ',.2f'  # set a default spec when not explicitly given
    return '$' + super().__format__(spec)

来自链接文档:

Called by the format() built-in function, and by extension, evaluation of formatted string literals and the str.format() method, to produce a “formatted” string representation of an object. The format_spec argument is a string that contains a description of the formatting options desired. The interpretation of the format_spec argument 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.

您现在要放弃 __str____repr__ 实现,或者至少不要在 __format__ 现在添加的 '$' 之上添加另一个 ( format(self, ...) 将触发)。

演示:

>>> 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: 3.44
>>> print(f"Amount: {m}")
Amount: 3.44