f 字符串表示与 str() 不同

Dan*_*ker 73 python enums f-string

我一直认为 f 字符串会调用该__str__方法。也就是说,f'{x}'始终与 相同str(x)。然而,有了这个班级

class Thing(enum.IntEnum):
    A = 0
Run Code Online (Sandbox Code Playgroud)

f'{Thing.A}''0'str(Thing.A)'Thing.A'enum.Enum如果我用作基类,此示例将不起作用。

f 字符串调用什么功能?

dec*_*ory 101

来自Python参考中的“格式化字符串文字”:f-strings调用“format()协议”,这意味着__format__调用魔术方法而不是__str__.

class Foo:
    def __repr__(self):
        return "Foo()"

    def __str__(self):
        return "A wild Foo"
    
    def __format__(self, format_spec):
        if not format_spec:
            return "A formatted Foo"
        return f"A formatted Foo, but also {format_spec}!"

>>> foo = Foo()
>>> repr(foo)
'Foo()'
>>> str(foo)
'A wild Foo'
>>> format(foo)
'A formatted Foo'
>>> f"{foo}"
'A formatted Foo'
>>> format(foo, "Bar")
'A formatted Foo, but also Bar!'
>>> f"{foo:Bar}"
'A formatted Foo, but also Bar!'
Run Code Online (Sandbox Code Playgroud)

如果您不想__format__被调用,可以在表达式后指定!s(for str)、!r(for repr) 或!a(for ):ascii

>>> foo = Foo()
>>> f"{foo}"
'A formatted Foo'
>>> f"{foo!s}"
'A wild Foo'
>>> f"{foo!r}"
'Foo()'
Run Code Online (Sandbox Code Playgroud)

这对于字符串有时很有用:

>>> foo = Foo()
>>> f"{foo}"
'A formatted Foo'
>>> f"{foo!s}"
'A wild Foo'
>>> f"{foo!r}"
'Foo()'
Run Code Online (Sandbox Code Playgroud)


Tim*_*ker 39

Python 中的 f 字符串不使用__str__or __repr__。他们使用__format__。因此,要获得与 相同的结果f'{Thing.A}',您需要调用format(Thing.A).

__format__(...)方法允许您添加更多格式功能(例如,您可以使用浮点数{:.2f}将数字四舍五入到小数点后两位)。

如果format()没有为类/对象定义,python 将回退到__str__. 这就是为什么大多数人认为str()是 f 字符串中使用的方法。

__format__该文档详细介绍了您可以使用的选项:链接到文档