Python string format: When to use !s conversion flag

后端 未结 3 941
感动是毒
感动是毒 2020-12-17 09:28

What\'s the difference between these 2 string format statements in Python:

\'{0}\'.format(a)
\'{0!s}\'.format(a)

Both have the same output

相关标签:
3条回答
  • 2020-12-17 10:05

    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 calls str() on the value, and '!r' which calls repr().

    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"
    
    0 讨论(0)
  • 2020-12-17 10:13

    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.

    0 讨论(0)
  • 2020-12-17 10:24

    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>'
    
    0 讨论(0)
提交回复
热议问题