【问题标题】:Why don't f-strings play nicely with dictionaries?为什么 f-strings 不能很好地与字典配合使用?
【发布时间】:2019-04-26 05:17:59
【问题描述】:

here 所述,f 字符串在与字典一起使用时表现不佳。

这是一个不太好的行为示例:

d = {'foo': 'bar'}

# Both work as expected
d["foo"]
d['foo']

# This only works when different quotations are used in the inner and outer strings
f'{d["foo"]}'
f"{d['foo']}"

# This doesn't work
f'{d['foo']}'
f"{d["foo"]}"

# The .format() method doesn't care
'{}'.format(d['foo'])

列出的最后两个 f 字符串导致 SyntaxError: invalid syntax,这是因为字符串 '{d['foo']}' 被评估为 '{d['foo']}'

在使用旧的.format() 方法时,f-strings 大括号内的所有内容都没有被单独评估的根本原因是什么?以这种方式实现 f-strings 的可能原因是什么?

我喜欢 f 弦,但这似乎支持旧方法。

【问题讨论】:

  • 如果' 不是指',你将如何标记字符串的结尾?
  • 支持format 的另一点是您可以省略围绕索引键的字符串分隔符,例如'{}'.format(d[foo]),除非它们包含一个数字(或者是一个),这很奇怪。

标签: python string python-3.x syntax-error


【解决方案1】:

F 字符串是文字字符串。在引号(相同类型)中包含未转义的引号是无效的语法。这是有道理的,因为结果是模棱两可的:解释器不知道字符串何时结束。在引号中包含引号的traditional way 之一是使用反斜杠。但是PEP498 禁止在 f 字符串中的表达式中使用反斜杠:

反斜杠不能出现在 f-strings...您可以在表达式中使用不同类型的引号...

因此,在给定 f 字符串表达式中的键的情况下访问字典值的唯一方法是使用不同类型的引号。使用单引号或双引号,到处都是模棱两可的,并给出SyntaxError

str.format 是一种常规方法,因此工作方式不同:d['foo'] 在构造字符串之前进行评估。就像将参数提供给函数一样,参数会在函数执行任何操作之前进行评估。

【讨论】:

  • 您的回答解释了为什么 format 表达式被单独评估,但它没有解决为什么 f-string 表达式不是。
  • @MagnusLindOxlund,我已经更新了我的答案,并相信它充分回答了这个问题,重点是如何在引号中加入引号。
  • 我同意它展示了如何解决问题,并且我已从您的答案中删除了反对票,但问题询问了设计背后的原因。我试图回答这个问题。
【解决方案2】:

这与f-strings 无关。 f 字符串是经过评估的常见字符串。你正在尝试的也会是标准字符串的问题

问题是

'a "b" c' 

is 声明文字 a "b" c

同时

'a 'b' c'

报价关闭并重新打开。所以,它相当于字符串a,后面跟着变量b,后面跟着字符串c

这就是python支持这两种引号的全部原因

【讨论】:

  • F-strings 是常见的字符串,一旦被评估,但不是在评估之前。他们存在的全部理由是暂停字符串文字的约束,同时将它们组合起来以编程方式合成字符串。问题是:当我们用大括号来标记其中的表达式时,为什么 f 字符串会受到字符串分隔符的约束?
【解决方案3】:

根据PEP 498,f-strings 依赖于常规字符串文字的实现,因此受到相同的约束。除此之外,f 字符串还有自己的约束条件,例如在表达式中的任何位置都排除反斜杠。

尚未公布选择实现的理由,但在可公开访问的邮件列表中,核心开发人员之间的讨论中都提到了易于实现、向后兼容、语法突出显示以及与现有插值语法的一致性。1

争论的焦点是所提出的概念是构成具有特殊属性的字符串还是插入代码的字符串。2 前一种观点受到青睐。 PEP 536,体现了不同的观点,并寻求解除几个句法限制,随后被归档。

基于此讨论,达成了在表达式中禁止反斜杠的初步折衷方案,将字符串定界符反转作为在 f 字符串表达式中索引字典的唯一剩余选项。


  1. 选择 f-string 引入 (Python 3.6) 之前的讨论:

    [Python-ideas] Briefer string format
    Re: [Python-ideas] Briefer string format
    Re: [Python-ideas] Briefer string format
    [Python-ideas] String interpolation for all literal strings
    [Python-Dev] PEP-498: Literal String Formatting
    @987654328 @
    [Python-Dev] PEP 498 href="interpolated f-string" tweak
    [Python-Dev] Parsing f-strings from PEP 498 -- Literal String Interpolation

  2. [Python-ideas] Let’s make escaping in f-literals impossible

【讨论】:

  • 但是 f-strings 甚至不应该看到那些反斜杠,至少经典词法分析器不会。所以,他们是一个奇怪的,非常奇怪(而且丑陋的)混合体。
猜你喜欢
  • 2014-07-04
  • 1970-01-01
  • 2011-02-27
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多