为什么 F 弦与字典不能很好地配合?

问题描述 投票:0回答:4

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

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

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 字符串大括号内的所有内容都不会单独计算的根本原因是什么?以这种方式实现 f 字符串的可能原因是什么?

我喜欢 F 弦,但这似乎是支持旧方法的一点。

python string python-3.x syntax-error
4个回答
6
投票

F 字符串是文字字符串。在引号(相同类型)中包含未转义的引号是无效语法。这是有道理的,因为结果是不明确的:解释器不知道字符串何时结束。在引号中包含引号的一种“传统方法”是使用反斜杠。但是 PEP498 禁止在 f 字符串内的表达式中使用反斜杠:

反斜杠不能出现在表达式部分内 f 字符串...您可以在表达式中
使用不同类型

的引号...

因此,访问给定 f 字符串表达式中的键的字典值的唯一方法是使用不同类型的引号。使用单引号或双引号,到处都会产生歧义并给出
SyntaxError


str.format

 是一种常规方法,因此工作方式有所不同:
d['foo'] 在构建字符串之前
进行评估。就像当您向函数提供参数时一样,在函数执行任何操作之前都会对参数进行求值。

这与

2
投票
字符串无关。

f

 字符串一旦被求值就是公共字符串。您所尝试的对于标准字符串来说也是一个问题
问题是

'a "b" c'

is 声明文字
a "b" c

同时

'a 'b' c'

报价关闭并重新打开。因此,它相当于字符串
a
,后跟变量

b

,后跟字符串 
c
这就是 python 支持两种类型引号的全部原因

Python 3.12 取消了使用围绕其中的 f 字符串的相同字符串分隔符的限制:

1
投票
# this now works f'{d['foo']}' #'bar' f"{d["foo"]}" #'bar'

此更改基于
PEP 701
,它引入了 f 字符串的正式语法,比该功能的第一个实现更宽松。

根据

0
投票
,f 字符串依赖于常规字符串文字的实现,因此受到相同的约束。除此之外,f 字符串还有自己的约束,例如在表达式中的任何位置排除反斜杠。

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

争论的中心点是所提出的概念是否构成具有特殊属性的字符串或插入代码的字符串。2

前一种观点受到青睐。

PEP 536,体现了不同意见,并另外寻求解除一些句法限制,随后被提交。 基于此讨论,就禁止表达式中的反斜杠达成了初步妥协,将字符串分隔符反转作为在 f 字符串表达式中索引字典的唯一剩余选项。


选择 f 字符串介绍之前的讨论 (Python 3.6):
  1. [Python-ideas] 更简短的字符串格式

    回复:[Python-ideas] 更简短的字符串格式
    回复:[Python-ideas] 更简短的字符串格式
    [Python-ideas] 所有文字字符串的字符串插值
    [Python-Dev] PEP-498:文字字符串格式
    [Python-Dev] PEP 498 f-string:它是预处理器吗?
    [Python-Dev] PEP 498 href="插值 f 字符串"调整
    [Python-Dev] 解析 PEP 498 中的 f 字符串——文字字符串插值


    [Python-ideas] 让 f 文字中的转义变得不可能
© www.soinside.com 2019 - 2024. All rights reserved.