【问题标题】:f-string representation different than str()f-string 表示不同于 str()
【发布时间】:2022-08-12 05:59:16
【问题描述】:

我一直认为 f-strings 调用了__str__ 方法。也就是说,f\'{x}\' 始终与str(x) 相同。但是,有了这个类

class Thing(enum.IntEnum):
    A = 0

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

f-strings 调用什么功能?

  • 在 Python3.11 中,str() 输出已更改为匹配 IntEnumIntFlag 和新的 StrEnum.format() 方法 - 所以在上述情况下 f\'{Thing.A}\'str(Thing.A) 将结果为0

标签: python enums f-string


【解决方案1】:

来自"Formatted string literals" in the Python reference: f 字符串调用“format 协议”,与 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!'

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

>>> foo = Foo()
>>> f"{foo}"
'A formatted Foo'
>>> f"{foo!s}"
'A wild Foo'
>>> f"{foo!r}"
'Foo()'

这有时对字符串有用:

>>> key = 'something\n nasty!'
>>> error_message = f"Key not found: {key!r}"
>>> error_message
"Key not found: 'something\\n nasty!'"

【讨论】:

    【解决方案2】:

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

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

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

    文档详细介绍了 __format__ 的选项:Link to Documentation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-22
      • 2021-10-01
      • 2011-04-21
      • 2019-10-29
      • 2015-04-14
      • 1970-01-01
      • 2015-02-01
      • 2014-08-19
      相关资源
      最近更新 更多