[英]Using !s vs. :s to format a string in Python
I'm really curious about :s
format string in Python 3. The documentation says !s
is conversion and that :s
is format_spec
. 我真的很好奇
:s
Python 3中:s
格式字符串。 文档说!s
是转换 ,并且:s
是format_spec
。
It also says !s
will apply str()
, but it doesn't say anything similar about :s
. 它还说
!s
将应用str()
,但它没有说类似的东西:s
。 I think there's no significant difference between them, but I want to be sure. 我认为它们之间没有显着差异,但我想确定。 Can anyone clarify these?
谁能澄清这些?
Some code example: 一些代码示例:
print("{!s}".format("this"))
print("{:s}".format("that"))
# I want to be sure that these two are processed identically internally
It's still confusing, but let me wrap up with my own (layperson's) words. 它仍然令人困惑,但让我用自己的(layperson)的话来结束。
type("whatever".format)
is always str
. type("whatever".format)
总是str
。 !s
if you want convert the object into str
before formatting. str
,请使用!s
。 :s
means that the object(or the converted object) will be treated as str
during some internal formatting process. :s
表示在某些内部格式化过程中,对象(或转换的对象)将被视为str
。 It's the default format_spec
. format_spec
。 Is anything wrong here? 这里有什么不对吗?
!s
, and its brethren !a
and !r
apply str()
, ascii()
and repr()
respectively before interpolation and formatting. !s
和它的兄弟!a
和!r
在插值和格式化之前分别应用str()
, ascii()
和repr()
。 These are called conversion flags , and are part of the Format String Syntax spec , not the per-field formatting spec applied to values when interpolating: 这些称为转换标志 ,是格式字符串语法规范的一部分 ,而不是插值时应用于值的每字段格式规范 :
The conversion field causes a type coercion before formatting .
转换字段在格式化之前导致类型强制。 Normally, the job of formatting a value is done by the
__format__()
method of the value itself.通常,格式化值的工作由值本身的
__format__()
方法完成。 However, in some cases it is desirable to force a type to be formatted as a string, overriding its own definition of formatting.但是,在某些情况下,最好强制将类型格式化为字符串,从而覆盖其自己的格式定义。 By converting the value to a string before calling
__format__()
, the normal formatting logic is bypassed.通过在调用
__format__()
之前将值转换为字符串,可以绕过普通的格式化逻辑。
Bold emphasis mine. 大胆强调我的。
:s
only applies afterwards to the conversion result (or the original object if no conversion had been applied), and only if the __format__
method for the type of object supports that formatting option. :s
仅在之后应用于转换结果(如果未应用转换,则仅适用于原始对象),并且仅当对象类型的__format__
方法支持该格式化选项时才应用。 Usually, only objects of type str
support this formatter; 通常,只有
str
类型的对象支持此格式化程序; it's there as the default, mostly because the Format Specification Mini-Language allows for the existence of a type character and because the older %
printf
-style formatting had a %s
format. 它是默认设置,主要是因为格式规范迷你语言允许存在类型字符,并且因为较旧的
%
printf
style格式具有%s
格式。 If you tried to apply the s
type to an object that doesn't support it, you'd get an exception. 如果您尝试将
s
类型应用于不支持它的对象,则会出现异常。
Use !s
(or !a
or !r
) when you have an object that is not itself a string and either doesn't support formatting otherwise (not all types do) or would format differently from their str()
, ascii()
or repr()
conversions: 当你有一个本身不是字符串的对象时,请使用
!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
Note: all formatting specified by the format spec are the responsibility of the __format__
method; 注意:格式规范指定的所有格式都是
__format__
方法的责任; the last line does not apply the alignment operation in the >50s
formatting spec, the Foo.__format__
method only used it as literal text in a formatting operation (using a !r
conversion here). 最后一行不适用于
>50s
格式规范中的对齐操作, Foo.__format__
方法仅在格式化操作中使用它作为文字文本(在此处使用!r
转换)。
For the converted values, on the other hand, the str.__format__
method is used and the output is aligned to the right in a 50 character wide field, padded with spaces on the left. 另一方面,对于转换后的值,使用
str.__format__
方法,输出在50字符宽的字段中右对齐,在左侧填充空格。
You're unlucky you used strings as the value to be formatted. 你不幸的是你使用字符串作为要格式化的值。 Using pretty much any other object you'd get how these aren't the same.
使用几乎任何其他对象,你会得到这些不一样的东西。
In (as much as I can) layman's terms: 在(尽我所能)外行人的条款:
__format__
we'll be calling. __format__
。 As Martjin points out, by using this we can bypass certain behavior and treat the value more generically (like a string). int
s, you can have different presentations. int
的类型,您可以使用不同的演示文稿。 I do think, though, that type
is probably a confusing name to give this specifier. 我确实认为,这种
type
可能是一个令人困惑的名称来给这个说明符。
From the documentation, Python String Formatting : 从文档中, Python字符串格式 :
The field_name is optionally followed by a conversion field, which is preceded by an exclamation point '!', and a format_spec, which is preceded by a colon ':'.
field_name后面跟一个转换字段,前面有一个感叹号'!'和一个format_spec,前面有冒号':'。
So no, it's not the same. 所以不,它不一样。
For example: 例如:
If you want to print a float as a string, you need a conversion (float → string). 如果要将float打印为字符串,则需要转换(float→string)。
"{!s}".format(2.1457)
>>> 2.1457
type("{!s}".format(2.1457))
>>> <type 'str'>
If you don't use the conversion mark, you will get an error. 如果您不使用转换标记,则会出现错误。
"{:s}".format(2.1457)
>>> ValueError: Unknown format code 's' for object of type 'float'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.