!s
, and its brethren !a
and !r
apply str()
, ascii()
and repr()
respectively before interpolation and formatting. 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. 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.
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. Usually, only objects of type str
support this formatter; 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. If you tried to apply the s
type to an object that doesn't support it, you'd get an exception.
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:
>>> 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
Note: all formatting specified by the format spec are the responsibility of the __format__
method; 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).
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…