Python字符串格式化:何时使用!s转换标志
这两种字符串格式化的语句在Python中有什么区别呢:
'{0}'.format(a)
'{0!s}'.format(a)
如果a
是一个整数、列表或字典,这两种方式的输出是一样的。第一个{0}
是不是在隐式地调用str()
呢?
附注:关键词:感叹号 / bang "!s" 格式化
3 个回答
2
感谢@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>'
28
简单来说:
'{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__
方法应该检查 specifiers 参数的类型,以决定返回字符串还是unicode对象。__format__
方法有责任返回正确类型的对象。
37
文档中提到:
转换字段会在格式化之前进行类型转换。通常,格式化一个值的工作是由这个值自己的
__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"