使用!s与:s在Python中格式化字符串
问题描述
我对Python3中的:s
格式字符串非常好奇。The documentation说!s
是!s
转换,:s
是format_spec
。
它还说!s
将应用str()
,但它没有说任何关于:s
的类似内容。我认为它们之间没有显著差异,但我想确定一下。有人能澄清这些吗?
一些代码示例:
print("{!s}".format("this"))
print("{:s}".format("that"))
# I want to be sure that these two are processed identically internally
这仍然令人困惑,但让我用我自己(外行)的话来总结一下。
type("whatever".format)
始终为str
。- 如果要在格式化前将对象转换为
str
,请使用!s
。 :s
表示对象(或转换后的对象)在某个内部格式化过程中将被视为str
。默认设置format_spec
。
这里有什么问题吗?
解决方案
!s
,其兄弟!a
和!r
在前分别应用str()
、ascii()
和repr()
。这些被称为转换标志,是Format String Syntax spec的一部分,而不是per-field formatting spec在插入时应用于值:
转换字段在格式化前导致类型强制。通常,格式化值的工作由值本身的
__format__()
方法完成。但是,在某些情况下,需要强制将类型格式化为字符串,从而覆盖其自身的格式设置定义。通过在调用__format__()
之前将值转换为字符串,可以绕过正常的格式设置逻辑。
强调我的。
仅当该对象类型的__format__
方法支持该格式选项时,:s
才应用于转换结果(如果未应用转换,则应用于原始对象)。通常,只有str
类型的对象支持该格式化程序;它是默认的,主要是因为Format Specification Mini-Language允许类型字符的存在,而且较旧的%
printf
-style formatting具有%s
格式。如果尝试将s
类型应用于不支持该类型的对象,则会出现异常。
如果对象本身不是字符串,并且不支持其他格式(并非所有类型都支持),或者格式与其str()
、ascii()
或repr()
转换不同,请使用!s
(或!a
或!r
):
>>> class Foo:
... def __str__(self):
... return "Foo as a string"
... def __repr__(self):
... return "<Foo as repr, with åéæ some non-ASCII>"
... def __format__(self, spec):
... return "Foo formatted to {!r} spec".format(spec)
...
>>> print("""
... Different conversions applied:
... !s: {0!s:>60s}
... !r: {0!r:>60s}
... !a: {0!a:>60s}
... No conversions: {0:>50s}
... """.format(Foo()))
Different conversions applied:
!s: Foo as a string
!r: <Foo as repr, with åéæ some non-ASCII>
!a: <Foo as repr, with xe5xe9xe6 some non-ASCII>
No conversions: Foo formatted to '>50s' spec
注意:格式规范指定的所有格式由__format__
方法负责;>50s
格式规范中的最后一行不应用对齐操作,Foo.__format__
方法仅将其用作格式操作中的文字文本(此处使用!r
转换)。
另一方面,对于转换值,使用str.__format__
方法,输出在50个字符宽度的字段中右对齐,左侧用空格填充。
相关文章