使用!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个字符宽度的字段中右对齐,左侧用空格填充。
相关文章