我真的很好奇Python 3中的:s
格式字符串。The documentation说!s
是转换而:s
是{{ 1}}。
它还说format_spec
将适用!s
,但它没有说明与str()
类似的内容。我认为它们之间没有显着差异,但我想确定。任何人都可以澄清这些吗?
一些代码示例:
:s
它仍然令人困惑,但让我用我自己的(layperson)的话来结束。
print("{!s}".format("this"))
print("{:s}".format("that"))
# I want to be sure that these two are processed identically internally
始终为type("whatever".format)
。str
,请使用!s
。str
表示在某些内部格式化过程中,对象(或转换后的对象)将被视为:s
。这是默认的str
。这里有什么问题吗?
答案 0 :(得分:33)
!s
及其兄弟!a
和!r
分别适用str()
,ascii()
和repr()
插值和格式化。这些被称为转换标志,是Format String Syntax spec的一部分,而不是插值时应用于值的per-field formatting spec:
转换字段会在格式化之前导致类型强制 。通常,格式化值的工作是通过值本身的
__format__()
方法完成的。 但是,在某些情况下,最好强制将类型格式化为字符串,覆盖其自己的格式定义。通过在调用__format__()
之前将值转换为字符串,正常绕过格式化逻辑。
大胆强调我的。
:s
仅适用于转换结果(如果未应用转换,则仅适用于原始对象),且仅当对象类型的__format__
方法支持该格式化选项时才适用。通常,只有str
类型的对象支持此格式化程序;它是默认值,主要是因为Format Specification Mini-Language允许存在类型字符,并且因为较早的%
printf
-style formatting具有%s
格式。如果您尝试将s
类型应用于不支持它的对象,则会出现异常。
使用!s
(或!a
或!r
)当您的对象本身不是字符串且不支持格式化时(不是所有类型都支持)或者格式与str()
,ascii()
或repr()
次转化不同:
>>> 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 \xe5\xe9\xe6 some non-ASCII>
No conversions: Foo formatted to '>50s' spec
注意:格式规范指定的所有格式是__format__
方法的责任;最后一行不适用>50s
格式规范中的对齐操作,Foo.__format__
方法仅在格式化操作中将其用作文字文本(此处使用!r
转换)。
另一方面,对于转换后的值,使用str.__format__
方法,输出在50个字符宽的字段中右对齐,在左侧填充空格。
答案 1 :(得分:2)
你不幸的是你使用字符串作为要格式化的值。使用几乎任何其他对象,你会得到这些不一样的东西。
(尽我所能)外行人的条款:
__format__
。正如Martjin指出的那样,通过使用它,我们可以绕过某些行为并更一般地处理该值(如字符串)。它有三种不同的风格,对应于一个对象可以选择将自己表示为字符串的三种不同方式。int
这样的类型,您可以使用不同的演示文稿。我确实认为,type
可能是一个令人困惑的名称,无法给出这个说明符。
答案 2 :(得分:-1)
从文档 Python String Formatting :
field_name可选地后跟一个转换字段,前面有一个感叹号'!'和一个format_spec,前面有冒号':'。
所以不,它不一样。
例如:
如果要将float打印为字符串,则需要转换(float→string)。
"{!s}".format(2.1457)
>>> 2.1457
type("{!s}".format(2.1457))
>>> <type 'str'>
如果您不使用转换标记,则会收到错误。
"{:s}".format(2.1457)
>>> ValueError: Unknown format code 's' for object of type 'float'