niv*_*nin 34 python python-3.x python-3.6 f-string
我真的很想深入研究代码风格,从现在开始知道从现在开始使用新风格会更好.
我.format()在我的Python 3.5项目中使用了很多,并且我担心在下一个Python版本中它会被弃用,因为这种新的字符串文字.
>>> name = "Test"
>>> f"My app name is {name}."
'My app name is Test.'
Run Code Online (Sandbox Code Playgroud)
格式化的字符串功能是否完全取代旧的format()?
我理解它基于这样的想法:
简单比复杂更好.
但是,性能问题如何,它们之间是否存在差异?或者它只是一个简单的相同功能的外观?
Jim*_*ard 36
我担心在下一个Python版本中它会被弃用
不要,str.format不会出现(也没有理由)很快离开,引入f前缀字符串的PEP 甚至在其摘要中指出:
此PEP不建议删除或弃用任何现有的字符串格式化机制.
引入格式化字符串以解决格式化字符串的其他方法的一些缺点; 不要抛弃旧方法并强迫上帝 - 如果他们希望他们的代码适用于Python 3.6+,那么知道有多少项目要使用f-string.
至于这些的表现,似乎我最初怀疑它们可能更慢是错误的,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
Run Code Online (Sandbox Code Playgroud)
这些是在撰写本文时针对CPython存储库的主分支完成的; 他们肯定会有变化:
f-strings作为一项新功能,可能有可能进行优化 .format更快(例如,Speedup方法调用1.2x)但实际上,不要太担心速度,担心对你和他人来说更具可读性.
在许多情况下,这将是f-strings,但有一些情况下,哪里format比较好.
Aar*_*ron 23
为了建立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))
Run Code Online (Sandbox Code Playgroud)
结果是:
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
可以看到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
没有提到的一件事(这使旧技术的弃用变得不可能)是插值仅用于字符串文字.意思是,字符串在运行时呈现一次.模板不能再次使用更新的变量,例如:
str_template.format(args)
Run Code Online (Sandbox Code Playgroud)
另一种情况是i18n,其中使用了string.Template.没有较旧的技术,许多用例是不可能的.享受字符串插值,但不要在不合适的地方使用它,即需要可重用模板的地方.