持续多行f字符串的样式

时间:2018-01-26 23:38:26

标签: python python-3.6

任何流行的Python风格指南都表达了以下优先选择:

x = (f'One plus one is '
     f'equal to {1+1}')

x = ('One plus one is '
     f'equal to {1+1}')

对于不涉及插值的行省略f前缀是否有意义?它是否应该包含在一致性中?

1 个答案:

答案 0 :(得分:10)

如果您查看这两个选项中每个选项的生成字节代码,您会发现这两个选项都会产生相同的操作集:

>>> dis.dis("""f'One plus one is ' f'equal to {1+1}'""")
  1           0 LOAD_CONST               0 ('One plus one is equal to ')
              2 LOAD_CONST               1 (2)
              4 FORMAT_VALUE             0
              6 BUILD_STRING             2
              8 RETURN_VALUE
>>> dis.dis("""'One plus one is ' f'equal to {1+1}'""")
  1           0 LOAD_CONST               0 ('One plus one is equal to ')
              2 LOAD_CONST               1 (2)
              4 FORMAT_VALUE             0
              6 BUILD_STRING             2
              8 RETURN_VALUE

因此对于Python来说,这两者完全相同:字符串在编译时被连接,整个字符串被评估为格式字符串。

请注意,根据the PEP,f-strings实际上是在运行时连接的,以确保每个格式表达式都是独立计算的:

  

连接相邻的f字符串和常规字符串。常规字符串在编译时连接,并且f字符串在运行时连接。

这就是为什么以下示例将生成两个FORMAT_VALUE操作码:

>>> dis.dis("""f'{2+2}' f'{3+3}'""")
  1           0 LOAD_CONST               0 (4)
              2 FORMAT_VALUE             0
              4 LOAD_CONST               1 (6)
              6 FORMAT_VALUE             0
              8 BUILD_STRING             2
             10 RETURN_VALUE

这对于实际上不包含任何格式占位符的f字符串没有影响。这些仍然会在编译时连接起来:

>>> dis.dis("""f'foo' f'bar'""")
  1           0 LOAD_CONST               0 ('foobar')
              2 RETURN_VALUE

所以你可以只为常量字符串包含f前缀,当它们不包含格式表达式时,它们最终不会被作为格式字符串处理。

因此,在您的特定情况下,由于没有功能差异,并且两个选项都编译为相同的东西,因此将其作为纯粹的样式选择,每个人都必须自己回答。

如果您正在查看现有的样式指南,很可能它们还没有覆盖f字符串。但是,你可以使用与原始字符串相同的指南,尽管我个人不希望样式指南真正覆盖该区域。只需选择最佳,可读和最适合您的内容。毕竟,连续的字符串并不是 共同的(并且你更有可能为更长的字符串使用三引号)。