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

时间:2014-08-22 07:21:26

标签: python string string-formatting

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

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

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

Source

PS:关键词:感叹/爆炸"!s"格式化

3 个答案:

答案 0 :(得分:20)

文档中提到:

  

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

     

目前支持两种转换标志:“!s”调用   关于值的str(),以及调用!r的“repr()”。

可以采用一个例子(同样来自the documentation)来显示差异:

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

答案 1 :(得分:12)

简单地说:

  • '{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__方法的责任   返回正确类型的对象。

答案 2 :(得分:2)

感谢评论&amp;回答@ 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>'