Python 字符串格式:何时使用 !s 转换标志


Python

中这两个字符串格式语句有什么区别:

'{0}'.format(a)
'{0!s}'.format(a)

如果a是整数、列表或字典,则两者具有相同的输出。第一个{0}执行隐式str()调用吗?

PS:关键字:感叹号/砰"!s"格式

文档中提到:

转换字段在格式化之前会导致类型强制。 通常,格式化值的工作由__format__() 值本身的方法。但是,在某些情况下,需要 强制将类型格式化为字符串,覆盖其自身 格式的定义。通过将值转换为之前的字符串 调用 __format__() ,将绕过正常的格式逻辑。

目前支持两个转换标志:"!s"调用 str()值,!r调用repr() 的 ' '。

可以举一个例子(同样来自文档(来显示差异:

>>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
"repr() shows quotes: 'test1'; str() doesn't: test2"

简单地说:

  • '{0}'.format(a)将使用a.__format__()的结果来显示值
  • '{0!s}'.format(a)将使用a.__str__()的结果来显示值
  • '{0!r}'.format(a)将使用a.__repr__()的结果来显示值

>>> class C:
...     def __str__(self): return "str"
...     def __repr__(self): return "repr"
...     def __format__(self, format_spec): return "format as " + str(type(format_spec))
... 
>>> c = C()
>>> print "{0}".format(c)
format as <type 'str'>
>>> print u"{0}".format(c)
format as <type 'unicode'>
>>> print "{0!s}".format(c)
str
>>> print "{0!r}".format(c)
repr

关于__format__的第二个论点,引用PEP 3101"基于每个类型控制格式">

"format_spec"参数将是 字符串对象或 Unicode 对象,具体取决于 原始格式字符串。 __format__方法应测试类型 的说明符参数,以确定是返回字符串还是返回字符串 Unicode 对象。 这是__format__方法的责任 返回正确类型的对象。

感谢@hjpotter92的评论和回答的解释:

下面是一个显示差异的示例(当您重写 __format__ 方法时(

class MyClass:
    i = 12345
    def __format__(self, i):
        return 'I Override'
>>> obj = MyClass()
>>> '{0}'.format(obj)
'I Override'
>>> '{0!s}'.format(obj)
'<__main__.MyClass instance at 0x021AA6C0>'

最新更新