Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
153 views
in Technique[技术] by (71.8m points)

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.

It also says !s will apply str(), but it doesn't say anything similar about :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.

  1. type("whatever".format) is always str.
  2. Use !s if you want convert the object into str before formatting.
  3. :s means that the object(or the converted object) will be treated as str during some internal formatting process. It's the default format_spec.

Is anything wrong here?

question from:https://stackoverflow.com/questions/41630728/using-s-vs-s-to-format-a-string-in-python

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

!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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...