【问题标题】:Python string format: When to use !s conversion flagPython 字符串格式:何时使用 !s 转换标志
【发布时间】:2014-08-22 07:21:25
【问题描述】:

这2个字符串格式语句在Python中有什么区别:

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

如果a 是整数、列表或字典,则两者具有相同的输出。第一个 {0} 是在进行隐式的 str() 调用吗?

Source

PS:关键字:感叹号/砰“!s”格式

【问题讨论】:

    标签: python string string-formatting


    【解决方案1】:

    文档中有提到:

    转换字段在格式化之前会导致类型强制。 通常,格式化值的工作由__format__() 完成 值本身的方法。然而,在某些情况下,希望 强制将类型格式化为字符串,覆盖它自己的 格式的定义。通过将值转换为字符串之前 调用__format__(),绕过正常的格式化逻辑。

    目前支持两个转换标志:'!s',它调用 str() 在值上,'!r' 调用 repr()

    可以举一个例子(同样来自the documentation)来说明区别:

    >>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
    "repr() shows quotes: 'test1'; str() doesn't: test2"
    

    【讨论】:

    • 无论我使用{0} 还是{0!s} 和字符串参数来格式化,我都会得到相同的结果。 repr() 是怎么出现的?
    • @click {x}{x!s} 将为字符串和整数提供相同的结果。如果您定义了不同的 __format__()__str__()(例如,对于某些自定义类,如向量或复数等),则会发生类型强制。
    • 对于{}{!s},您几乎总是会得到相同的结果,因为this suggestion from the Python docs: A general convention is that an empty format string ("") produces the same result as if you had called str() on the value. 我所知道的所有内置类型都遵循这个约定。
    【解决方案2】:

    简单地说:

    • '{0}'.format(a) 将使用 a.__format__() 的结果来显示值
    • '{0!s}'.format(a) 将使用a.__str__() 的结果来显示值
    • '{0!r}'.format(a) 将使用a.__repr__() 的结果来显示值

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

    关于__format__ 的第二个参数,引用PEP 3101 “基于每种类型控制格式”

    “format_spec”参数将是 字符串对象或 unicode 对象,具体取决于 原始格式字符串。 __format__ 方法应该测试类型 的说明符参数来确定是否返回一个字符串或 Unicode 对象。这是__format__ 方法的职责 返回正确类型的对象。

    【讨论】:

      【解决方案3】:

      感谢@hjpotter92 的评论和回答的解释:

      这是一个显示差异的示例(当您覆盖 __format__ 方法时)

      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>'
      

      【讨论】:

        猜你喜欢
        • 2017-05-28
        • 2011-02-20
        • 1970-01-01
        • 1970-01-01
        • 2021-11-03
        • 2017-03-12
        • 2012-03-08
        • 2021-02-03
        • 1970-01-01
        相关资源
        最近更新 更多