Reputation: 2113
What's the difference between these 2 string format statements in Python:
'{0}'.format(a)
'{0!s}'.format(a)
Both have the same output if a
is an integer, list or dictionary. Is the first one {0}
doing an implicit str()
call?
PS: keywords: exclamation / bang "!s" formatting
Upvotes: 25
Views: 11507
Reputation: 52040
Simply said:
'{0}'.format(a)
will use the result of a.__format__()
to display the value'{0!s}'.format(a)
will use the result of a.__str__()
to display the value'{0!r}'.format(a)
will use the result of a.__repr__()
to display the value>>> class C:
... def __str__(self): return "str"
... def __repr__(self): return "repr"
... def __format__(self, format_spec): return "format as " + str(type(format_spec))
...
>>> c = C()
>>> print "{0}".format(c)
format as <type 'str'>
>>> print u"{0}".format(c)
format as <type 'unicode'>
>>> print "{0!s}".format(c)
str
>>> print "{0!r}".format(c)
repr
Concerning the second argument of __format__
, to quote PEP 3101 "Controlling Formatting on a Per-Type Basis":
The 'format_spec' argument will be either a string object or a unicode object, depending on the type of the original format string. The
__format__
method should test the type of the specifiers parameter to determine whether to return a string or unicode object. It is the responsibility of the__format__
method to return an object of the proper type.
Upvotes: 29
Reputation: 2113
Thanks to the comment & answer from @hjpotter92 for explanation:
Here's an example that shows the difference (it's when you override the __format__
method)
class MyClass:
i = 12345
def __format__(self, i):
return 'I Override'
>>> obj = MyClass()
>>> '{0}'.format(obj)
'I Override'
>>> '{0!s}'.format(obj)
'<__main__.MyClass instance at 0x021AA6C0>'
Upvotes: 2
Reputation: 80649
It is mentioned in the documentation:
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.Two conversion flags are currently supported: '
!s
' which callsstr()
on the value, and '!r
' which callsrepr()
.
An example can be taken (again from the documentation) to show the difference:
>>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
"repr() shows quotes: 'test1'; str() doesn't: test2"
Upvotes: 37