ChatGPT解决这个技术问题 Extra ChatGPT

Python 的多种字符串格式化方式——旧的(将要被)弃用了吗?

Python 至少有六种格式化字符串的方法:

In [1]: world = "Earth"

# method 1a
In [2]: "Hello, %s" % world
Out[2]: 'Hello, Earth'

# method 1b
In [3]: "Hello, %(planet)s" % {"planet": world}
Out[3]: 'Hello, Earth'

# method 2a
In [4]: "Hello, {0}".format(world)
Out[4]: 'Hello, Earth'

# method 2b
In [5]: "Hello, {planet}".format(planet=world)
Out[5]: 'Hello, Earth'

# method 2c
In [6]: f"Hello, {world}"
Out[6]: 'Hello, Earth'

In [7]: from string import Template

# method 3
In [8]: Template("Hello, $planet").substitute(planet=world)
Out[8]: 'Hello, Earth'

不同方法的简要历史:

printf 样式的格式从 Python 婴儿期就已经存在

模板类是在 Python 2.4 中引入的

在 Python 2.6 中引入了 format 方法

f-strings 是在 Python 3.6 中引入的

我的问题是:

printf 样式的格式是否已弃用或将被弃用?

在 Template 类中,替代方法是已弃用还是将要弃用? (我不是在谈论 safe_substitute,据我了解,它提供了独特的功能)

类似的问题以及为什么我认为它们不重复:

Python 字符串格式化:% 与 .format — 只处理方法 1 和 2,并询问哪个更好;我的问题是明确地根据 Python 的禅宗弃用

字符串格式选项:优点和缺点 — 仅处理问题中的方法 1a 和 1b,答案中的 1 和 2,也没有关于弃用

高级字符串格式化与模板字符串——主要是关于方法 1 和 3,并且不涉及弃用

字符串格式化表达式(Python)——答案提到原始的 '%' 方法计划被弃用。但是计划弃用、待弃用和实际弃用之间有什么区别?而且 printf 风格的方法甚至不会引发 PendingDeprecationWarning,所以这真的会被弃用吗?这个帖子也很老了,所以信息可能已经过时了。

也可以看看

PEP 502:字符串插值 - 扩展讨论

字符串格式化程序

我需要指出您忘记了 Formatter 类吗?

M
Mark Amery

新的 .format() method 旨在替换旧的 % 格式语法。后者已被淡化,(但尚未正式弃用)。方法文档说明了很多:

这种字符串格式化方法是 Python 3 中的新标准,应该优先于新代码中字符串格式化操作中描述的 % 格式化。

(强调我的)。

为了保持向后兼容性并使过渡更容易,旧格式暂时保留。从原始 PEP 3101 proposal

向后兼容性 向后兼容性可以通过保留现有机制来保持。新系统不会与现有字符串格式化技术的任何方法名称发生冲突,因此两个系统可以共存,直到需要弃用旧系统。

请注意,直到弃用旧系统为止;它还没有被弃用,但新系统将在您编写新代码时使用。

新系统的优势在于您可以结合% 格式化程序的元组和字典方法:

"{greeting}, {0}".format(world, greeting='Hello')

并且可以通过用于处理单个值格式的 object.__format__() 挂钩进行扩展。

请注意,旧系统具有 %Template 类,后者允许您创建添加或更改其行为的子类。新型系统具有 Formatter class 来填补相同的利基。

Python 3 已进一步远离弃用,而是在 printf-style String Formatting section 中向您发出警告:

注意:此处描述的格式化操作有多种怪癖,这些怪癖会导致一些常见错误(例如无法正确显示元组和字典)。使用较新的格式化字符串文字或 str.format() 接口有助于避免这些错误。这些替代方案还提供了更强大、更灵活和可扩展的文本格式设置方法。

Python 3.6 还添加了 formatted string literals,它将表达式嵌入格式字符串。这些是创建具有内插值的字符串的最快方法,并且应该在可以使用文字的任何地方代替 str.format() 使用。


使用 Formatter,您可以创建自定义格式,例如 datetime 对象使用的格式。此外,由于 .format 是一个函数,您可以使用它更直接地创建可调用的惰性格式:例如,fmt = '{} - {}'.format; fmt(a, b)
我看不出 Template%旧系统有什么关系。特别是您链接的 PEP 指出 虽然此提案和 string.Template 之间存在一些重叠,但我们认为每个提案都有不同的需求,并且其中一个不会排除另一个。在您的回答中,一个可能会感到困惑的是,作为 旧系统 的一部分的 Template 格式也已被弃用。
[...]should be preferred to the % formatting[...] 这部分已从文档中删除。 docs.python.org/3/library/stdtypes.html#str.format
我认为这个答案目前具有误导性;引用的第一段已从 Python 3 文档中删除,对我来说似乎很清楚,没有任何弃用的意图。这个答案仍然具有历史价值,但我倾向于调整措辞以避免任何关于弃用仍在卡片中的建议,并将答案的前半部分大部分内容编辑为过去时。如果你不反对,我会在某个时候自己这样做,但我想我会先发表评论,让你有机会自己做出这样的改变,如果你愿意的话。
@MartijnPieters 够公平的。我坚持对这个答案的批评;我认为您在 Python 2 文档中剩余的散文中阅读任何内容都是错误的,并且认为由于我概述 in my answer 以及其他人在此处的其他答案中给出的原因,绝对没有弃用的前景,但我不会编辑从根本上改变您对您不同意的答案的含义。
j
jsbueno

用于字符串格式化的 % 运算符并未被弃用,也不会被删除 - 尽管有其他答案。
每次在 Python 开发列表中提出该主题时,关于哪个更好,都会有激烈的争论,但没有关于是否删除经典方式的争议- 它会留下来。尽管在 PEP 3101 上有所表示,但 Python 3.1 来来去去,% 格式仍然存在。

保持经典风格的陈述很明确:简单,快速,做短小的事情很快。使用 .format 方法并不总是更具可读性 - 几乎没有人 - 即使在核心开发人员中,也可以使用 .format 提供的完整语法而无需查看参考 甚至早在 2009 年,就有这样的消息: http://mail.python.org/pipermail/python-dev/2009-October/092529.html - 从那以后,该主题几乎没有出现在列表中。

2016 年更新

在当前的 Python 开发版本(将成为 Python 3.6)中,存在第三种字符串插值方法,如 PEP-0498 所述。它定义了一个新的引号前缀 f""(除了当前的 u""b""r"")。

通过 f 为字符串添加前缀将在运行时调用字符串对象的方法,该方法会自动将当前作用域中的变量插入到字符串中:

>>> value = 80
>>> f'The value is {value}.'
'The value is 80.'

允许类型实现它们自己的 __format__ 会更好。例如,format(Decimal('0.1'), '.20f')'%.20f' % Decimal('0.1')。后者将 Decimal 强制为浮点数。
注意。我并没有争辩说旧风格在所有方面都更好——只是它更短,有时更易读(有时不是)。当然,新方式要灵活得多。
Python 3 中有 f 的等价物吗?
上面使用的 f-strings 是 Python 3.6 语言中的新功能。它在以前的版本中不存在,并且会在这些版本上引发语法错误。
此外,在 f 字符串中,不仅如所写的那样插入变量,而且还包括任意表达式,可能包括任意函数和任意代码。
M
Mark Amery

查看较旧的 Python 文档和 PEP 3101 有一个声明,即 % 运算符将在未来被弃用并从语言中删除。 following statement 在 Python 3.0、3.1 和 3.2 的 Python 文档中:

由于 str.format() 很新,很多 Python 代码仍然使用 % 运算符。但是,由于这种旧式格式最终会从语言中删除,因此通常应该使用 str.format()。

如果您转到 Python 3.3 和 3.4 文档中的 same section,您将看到该语句已被删除。我在文档中的其他任何地方也找不到任何其他声明,表明该运算符将被弃用或从该语言中删除。还需要注意的是,PEP3101 已超过两年半(星期五,2011 年 9 月 30 日)未修改。

更新

PEP461 接受向字节和字节数组添加 % 格式,并且应该是 Python 3.5 或 3.6 的一部分。这是 % 操作符还活着并且在踢的另一个迹象。


M
Mark Amery

虽然文档中有各种迹象表明 .format 和 f-strings 优于 % 字符串,但没有幸存的计划来弃用后者。

在提交 Issue #14123: Explicitly mention that old style % string formatting has caveats but is not going away any time soon. 中,受问题 Indicate that there are no current plans to deprecate printf-style formatting 的启发,对 % 格式的文档进行了编辑以包含以下短语:

由于新的字符串格式化语法更加灵活并且可以自然地处理元组和字典,因此建议用于新代码。但是,目前没有弃用 printf 样式格式的计划。

(强调我的。)

该短语后来在提交 Close #4966: revamp the sequence docs in order to better explain the state of modern Python 中被删除。这似乎表明弃用 % 格式的计划重新出现在卡片上……但深入研究错误跟踪器会发现其意图恰恰相反。在错误跟踪器上,提交的作者描述了更改 like this

更改了描述 printf 样式格式和 str.format 方法之间关系的散文(故意消除前者存在真正消失的危险的暗示——我们认真考虑将其杀死是不切实际的)

换句话说,我们对 % 格式文档进行了两次连续更改,旨在明确强调它不会被弃用,更不用说将其删除了。文档仍然对不同类型的字符串格式的相对优点持意见,但他们也很清楚 % 格式不会被弃用或删除。

更重要的是,most recent change to that paragraph 在 2017 年 3 月将其更改为...

此处描述的格式化操作表现出各种怪癖,这些怪癖会导致许多常见错误(例如无法正确显示元组和字典)。使用较新的格式化字符串文字或 str.format 接口有助于避免这些错误。这些替代方案还提供了更强大、更灵活和可扩展的文本格式设置方法。

...对此:

此处描述的格式化操作表现出各种怪癖,这些怪癖会导致许多常见错误(例如无法正确显示元组和字典)。使用较新的格式化字符串文字、str.format 接口或模板字符串可能有助于避免这些错误。这些替代方案中的每一个都提供了它们自己的权衡和简单性、灵活性和/或可扩展性的好处。

请注意从“帮助避免”到“可能帮助避免”的变化,以及 .format 和 f 字符串的明确推荐如何被关于每种风格 “如何提供自己的权衡的蓬松、模棱两可的散文所取代和好处”。也就是说,不仅不再正式弃用卡片,而且当前的文档公开承认 % 格式至少比其他方法有一些“好处”。

我从这一切推断出,弃用或删除 % 格式的运动不仅步履蹒跚,而且被彻底和永久地打败了。


添加了蓬松的语言更改以安抚不希望看到 Mercurial 的代码库太大而无法根除使用 % 的 Mercurial 维护者(以及其他维护者)。既然“没有大规模代码模组”的政策已经被取消,他们的反对意见也正在消退。从长远来看,维护这两种形式而没有任何好处% 在某些时候无论如何都会删除 printf 语法。我们只是不知道什么时候,所以语言是值得的。
@MartijnPieters 很有趣。听起来你对我缺乏的这个决定有很多了解。对于它的价值,我认为您概述这些要点的参考充分的答案(作为新答案或对现有答案的编辑)将具有价值。
L
Lev Levitsky

Guido 在这方面的最新立场似乎在这里表明:

What’s New In Python 3.0

PEP 3101:字符串格式化的新方法 用于内置字符串格式化操作的新系统取代了 % 字符串格式化操作符。 (但是,仍然支持 % 运算符;它将在 Python 3.1 中弃用,并在稍后从该语言中删除。)阅读 PEP 3101 以获得完整的独家新闻。

还有 PEP3101 本身,它的最后一次修改可以追溯到(2011 年 9 月 30 日星期五),所以我想最近在那个方面没有任何进展。