Python 改进 f-strings 语法,解除封印,整合到统一的解析器中


多元共进|2023 Google 开发者大会精彩演讲回顾

在将于 10 月初发布的 Python 3.12 中,我们将看到 f-strings 语法带来了一些变化,新版取消了最初制定 f-strings 时制定的一些限制。经过这些变化,使得 f-strings 更加统一,成为一种可以直接整合到解析器中的正式化语法。这将会为终端用户和库开发者带来较大优势,同时也大大降低用于解析 f-strings 代码的维护成本。

 

最初设置 f-strings 限制是为了能够在不修改现有词法分析器的情况下将 f-strings 的解析实现到 CPython 中。但目前来看,这些限制反而带来了复杂性。比如:

  1. 在表达式部分中,无法使用引号字符来界定 f-strings
    >>> f'Magic wand: { bag['wand'] }'
     ^
    SyntaxError: invalid syntax
  2. 之前考虑过的一种解决方法会导致在执行的代码中出现转义序列,这在 f-strings 中是被禁止的:
    >>> f'Magic wand { bag[\'wand\'] } string'
    SyntaxError: f-string expression portion cannot include a backslash
  3. f-strings 中无法使用注释语法:
    >>> f'''A complex trick: {
    ... bag['bag']# recursive bags!
    ... }'''
    SyntaxError: f-string expression part cannot include '#'
  4. 许多其它语言表达式字符串插值都支持不扩展转义序列的任意嵌套。比如:
    # Ruby
    "#{ "#{1+2}" }"
    
    # JavaScript
    `${`${1+2}`}`
    
    # Swift
    "\("\(1+2)")"
    
    # C#
    $"{$"{1+2}"}"

Python 团队意识到,从语言用户的角度来看,这些限制没有任何意义,所以他们目前通过赋予 f-strings 字面量一个没有例外的常规语法,并使用专用的解析代码来实现它,从而消除这些限制。

f-strings 的另一个问题是,CPython 中的当前实现依赖于将 f-strings 标记化为 STRING 令牌,并对这些令牌进行后处理。这带来了以下问题:

  1. 它给 CPython 解析器增加了相当大的维护成本。这是因为解析代码需要手动编写,这在历史上导致了大量的不一致性和错误。在 C 中手动编写和维护解析代码一直被认为是容易出错和危险的,因为它需要处理大量的原始词法分析器缓冲区上的手动内存管理。
  2. f-strings 解析代码无法使用新的 PEG 解析器所允许的新错误消息机制,这些错误消息带来的改进已经受到了热烈欢迎,但因为 f-strings 用的是独立解析器,所以无法使用上新改进的错误消息机制。另外,因为 f-strings 有几个语法特性可能会因为在表达式部分内部发生的不同隐式标记化而令人困惑(例如 f"{y:=3}" 并不是一个赋值表达式)。
  3. 其它 Python 实现无法知道它们是否正确实现了 f-strings,因为它们并不是官方 Python 语法的一部分。这一点很重要,因为有几个知名的替代实现正在使用 CPython 的 PEG 解析器,如 PyPy。f-strings 使用一个独立的解析器,阻止了这些替代实现利用官方语法,以及从改进的错误消息机制中受益。

期待新 f-strings 能用得更顺心。

具体情况可以查看 PEP-701:https://peps.python.org/pep-0701


相關推薦

2023-10-04

Python 3.12.0 已正式发布。 主要变化 更灵活的 f-string 解析 (PEP 701) 详情查看 Python 改进 f-strings 语法,解除封印,整合到统一的解析器中 支持 buffer 协议 (PEP 688) 引入新的 debugging/profiling API (PEP 669) 支持具有单

2023-08-08

: 针对泛型类的新类型注释语法 (PEP 695) 更灵活的 f-string 解析 (PEP 701) 支持 buffer 协议 (PEP 688) 改进错误消息 改进性能 支持 Linux perf 分析器在跟踪过程中报告 Python 函数名称 根据 PEP 623 提案,删除了 C 语言实

2023-09-08

: 针对泛型类的新类型注释语法 (PEP 695) 更灵活的 f-string 解析 (PEP 701) 支持 buffer 协议 (PEP 688) 改进错误消息 改进性能 支持 Linux perf 分析器在跟踪过程中报告 Python 函数名称 根据 PEP 623 提案,删除了 C 语言实

2023-05-05

众所周知,Python 是 AI 和 ML 领域最受欢迎的语言,如果翻看过去数月,甚至是数年的 TIOBE 榜单,Python 也一直占据着榜单前两名的位置。随着近段时间的 AI 的火热,以及 AI 在各个行业的应用,Python 受欢迎的程度有望进一步提升

2022-08-19

同时追踪多个记录,并且包含全新且功能强大的日志筛选语法。如需了解更多信息,请参阅 Android 开发者文档。 △ Logcat V2 由 Gradle 管理的设备 - 为自动化测试描述您所需的虚拟设备,并将其作为构建的一部分,同时

2022-09-13

态系统中的工具(包括 SourceKit-LSP 和 Swift 包管理器)的改进、改进的 Windows 支持等等。 语言和标准库 Swift 5.7 语言和标准库具有多项改进: 通用样板代码的新速记语法,包括if let语句和多语句 closure type annotations 解除

2022-10-23

用于编辑纯文本文件,如网页 HTML、CSS),程序源代码(Python、Ruby、Perl 等),结构化文本(Markdown、Textile、Tex 等)或任何其他类型的纯文本。 CotEditor 4.4 正式发布,该版本更新内容如下: 系统要求 macOS 12 及以上版本 新

2022-11-03

执行模式:“线程”模式。在该模式下,用户自定义的 Python 函数将通过 JNI 在 JVM 中执行,而不是在独立的 Python 进程中执行。但是,在 Flink 1.15 中,仅在 Table API 和 SQL 上的 Python 标量函数的执行上支持了该功能。在该版本中,

2024-02-03

p;#35222 ) [example] 更新 OTel 为 head。( #35151 ) Python [Python O11Y] 将 _registered_method 添加到 init .py。( #35482 ) [Python Otel] Re-apply Otel。( #35439 ) [python O11Y] 实现 OpenTelemetry。( #35292 ) Ruby

2023-04-02

了多种编程语言的优点,包括Rust的内存安全和并发性、Python的易用性和快速开发、以及JavaScript的动态性和灵活性等。这种综合特性使得开发人员能够更好地处理复杂的编程任务。 自动化内存管理:NGPTL++ 编程语言采用自动化

2023-12-31

下载地址:https://jsoup.org/download 具体更新内容包括: 改进 Attribute object accessors:添加Element.attribute(String)和Attributes.attribute(String)以便更简单地获取Attribute对象。2069 Attribute source tracking:如果 source tracking 已打开,并且属性

2023-08-04

件许可证的形式维护。为了方便插件,Sublime Text 有一个 Python API。 Sublime Text 4 Build 4151 & 4152 现已发布,具体更新内容包括: BUILD 4151 各种语法高亮显示改进 添加了“fold_style”设置来控制基于语法的代码折叠 现在

2022-08-24

+ 之外,CLion 还直接或通过插件支持其他语言,如 Kotlin、Python、Rust、Swift 等。 JetBrains 在几周前发布了 CLion 2022.2,该版本主要集中在 CMake 集成的增强、代码文档的改进,以及代码分析能力的扩展。CLion 2022.2 发布后,团队的工

2022-06-20

用于编辑纯文本文件,如网页 HTML、CSS),程序源代码(Python、Ruby、Perl 等),结构化文本(Markdown、Textile、Tex 等)或任何其他类型的纯文本。 CotEditor 4.3 正式发布,该版本更新内容如下: 系统要求 macOS 11 及以上版本 新