Python 3.6 中的 f 字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43123408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 22:32:59  来源:igfitidea点击:

f-strings in Python 3.6

pythonpython-3.xpython-3.6f-string

提问by nivhanin

I really like to delve into code style and it's interesting to know whether from now on in all cases it would be better to use the new style.

我真的很喜欢深入研究代码风格,很有趣的是,从现在开始,是否在所有情况下都使用新风格会更好。

I'm using a lot the .format()in my Python 3.5 projects, and I'm afraid that it will be deprecated during the next Python versions because of this new kind of string literals.

.format()在我的 Python 3.5 项目中使用了很多,我担心它会在下一个 Python 版本中被弃用,因为这种新的字符串文字。

>>> name = "Test"
>>> f"My app name is {name}."
'My app name is Test.'

Does the formatted string feature come to fully replace the old format()?

格式化字符串功能是否完全取代了旧的format()

I understand that it based on the idea that:

我理解它基于以下想法:

Simple is better than complex.

简单胜于复杂。

However, what about performance issues, does any difference exist between them? Or is it just a simple look of the same feature?

但是,性能问题呢,它们之间有什么区别吗?或者它只是相同功能的简单外观?

回答by Dimitris Fasarakis Hilliard

I'm afraid that it will be deprecated during the next Python versions

我担心它会在下一个 Python 版本中被弃用

Don't be, str.formatdoes not appear (nor has a reason) to be leaving any time soon, the PEP that introduced fprefixed-strings even states in its Abstract:

不要,str.format不会(也没有理由)很快离开,引入f前缀字符串的 PEP甚至在其摘要中声明

This PEP does not propose to remove or deprecate any of the existing string formatting mechanisms.

本 PEP 不建议删除或弃用任何现有的字符串格式化机制。

Formatted strings were introduced to address some of the shortcomings other methods for formatting strings had; not to throw the old methods away and force god-knows how many projects to use f-string's if they want their code to work for Python 3.6+.

引入格式化字符串是为了解决其他格式化字符串方法的一些缺点;如果他们希望他们的代码适用于 Python 3.6+,不要扔掉旧方法并强迫天知道有多少项目使用 f-string。



As for the performance of these, it seems my initial suspicion that they might be slower is wrong, f-strings seem to easily outperform their .formatcounterparts:

至于这些的性能,我最初怀疑它们可能更慢似乎是错误的,f-strings 似乎很容易胜过它们的.format对应物:

? cpython git:(master) ./python -m timeit -s "a = 'test'" "f'formatting a string {a}'"
500000 loops, best of 5: 628 nsec per loop
? cpython git:(master) ./python -m timeit "'formatting a string {a}'.format(a='test')"
100000 loops, best of 5: 2.03 usec per loop

These were done against the master branch of the CPython repository as of this writing; they are definitely subject to change:

在撰写本文时,这些是针对 CPython 存储库的 master 分支完成的;它们肯定会发生变化:

  • f-strings, as a new feature, might have possible optimizations
  • Optimizations to CPython might make .formatfaster (e.g Speedup method calls 1.2x)
  • f-strings,作为一个新功能,可能会有优化
  • 对 CPython 的优化可能会.format更快(例如Speedup 方法调用 1.2x

But really, don't worry about speed so much, worry about what is more readable to you and to others.

但实际上,不要太担心速度,而要担心对您和其他人来说更易读的内容。

In many cases, that's going to be f-strings, but there's some caseswhere formatis better.

在许多情况下,这将是f-strings,但在某些情况format更好。

回答by Aaron

To build on Jim's answer and address your performance concern, I used python's dismodule to compare the bytecode instructions for two syntactically different, but functionally equivalent functions.

为了以 Jim 的回答为基础并解决您的性能问题,我使用 python 的dis模块来比较两个语法不同但功能相同的函数的字节码指令。

import dis

def f1():
    a = "test"
    return f"{a}"

def f2():
    return "{a}".format(a='test')

print(dis.dis(f1))
print(dis.dis(f2))

The result of which is:

其结果是:

 11           0 LOAD_CONST               1 ('test')
              2 STORE_FAST               0 (a)

 12           4 LOAD_FAST                0 (a)
              6 FORMAT_VALUE             0
              8 RETURN_VALUE
None
 15           0 LOAD_CONST               1 ('{a}')
              2 LOAD_ATTR                0 (format)
              4 LOAD_CONST               2 ('test')
              6 LOAD_CONST               3 (('a',))
              8 CALL_FUNCTION_KW         1
             10 RETURN_VALUE
None

One can see that the f-string handles the formatting without attribute or function calls, which can impose type checking and memory overhead. According to timeitthis results in a roughly 3x performance gain (for my specific functions)

可以看到 f-string 在没有属性或函数调用的情况下处理格式,这会强加类型检查和内存开销。根据timeit这个结果,性能提高了大约 3 倍(对于我的特定功能)

>>> timeit.timeit('f1()', 'from __main__ import f1', number=100000)
0.012325852433775708
>>> timeit.timeit('f2()', 'from __main__ import f2', number=100000)
0.036395029920726074

回答by Gringo Suave

One thing not mentioned, which makes deprecation of the old techniques impossible, is that interpolation is for string literals only. Meaning, the string is rendered once at runtime. The template is not available to be used again with updated variables. As you would for example:

没有提到的一件事使旧技术无法弃用,即插值仅适用于字符串文字。意思是,字符串在运行时呈现一次。该模板不可再次用于更新的变量。例如:

str_template.format(args)

Another case is i18n, where string.Template is used. Many use cases would be impossible without the older techniques. Enjoy string interpolation, but it is not available to every use case, i.e. places where you need a reusable template.

另一种情况是 i18n,其中使用 string.Template。如果没有旧的技术,许多用例将是不可能的。享受字符串插值,但它不适用于每个用例,即您需要可重用模板的地方。

回答by RinSlow

If you want to keep supporting python 3.5 you could use fstring

如果你想继续支持 python 3.5,你可以使用 fstring

pip install fstring

pip install fstring

from fstring import fstring

x = 1

y = 2.0

plus_result = "3.0"

print fstring("{x}+{y}={plus_result}")

# Prints: 1+2.0=3.0