探索Python F-strings是如何工作
PEP 498 提出一种新型字符串格式化机制,被称为“字符串插值”或者更常见的一种称呼是F-strings(主要因为这种字符串的第一个字母是f)。F-strings提供了一种明确且方便的方式将python表达式嵌入到字符串中来进行格式化:
同样的,在F-strings中我们也可以执行函数:
F-strings的运行速度很快。比%-string和str.format()这两种格式化方法都快得多——这两种是最常用的两种字符串格式化的方式。
为什么F-strings的运行速度这么快?它们是以怎样的形式运行得呢?PEP 498给出了如下的线索:
使用最小的语法,F-strings提供了一种在字符串中嵌入表达式的方法。需要注意的是,F-strings是运行过程中形成的表达式,而不是常数值。在Python源代码中,F-strings是一个以f为前缀,其中包含了表达式的字符串。表达式的结果将显示在其所在的位置上。
重点是F-strings是运行过程中进行计算的表达式,而不是一个常数值。这意味着F-strings和其他python表达式一样都是在运行过程中计算出结果的。CPython编译器在将F-strings解析成字符串和表达式以生成合适的抽象语法树的阶段使性能得到巨大的提升:
我们使用ast模块来查看一个简单的表达式a + b在F-strings之中和之外两种情况下的抽象语法树的情况。可以看到表达式F-strings中的表达式被解析成一个普通的旧式的二进制操作,和单独的表达式 a + b解析成的结果是一样的。甚至在字节码层面我们也可以看到F-strings表达式也像普通表达式那样进行计算。
add_two函数简单的将两个本地变量a和b进行相加并返回结果值。add_two_fstring函数实现的功能类似,但相加的表达式放到f-strings内。在add_two_fstring函数反汇编出的字节码中,FORMAT_VALUE指令(这个指令出现在这里因为毕竟一个F-strings需要将其内部的表达式字符串化),和不使用F-strings的 a + b表达式的结果是一样的。
F-strings的过程主要分为两步:一是把花括号中的表达式计算出来(和普通的Python表达式一样),然后将其结果填充到花括号的位置,并将组合后的字符串作为结果返回。这些步骤不需要额外的运行过程处理。这使得F-strings运行速度更快也更有效率。
为何str.format()会比F-strings慢得多呢?当看过其对应的反汇编字节码之后,原因就很明显了。
反汇编得到的字节码中,第一眼就能看到两个字节码指令:LOAD_ATTR 和 CALL_FUNCTION。当我们使用上str.format()时,首先要在全局范围内寻找format函数。这个步骤是通过LOAD_ATTR 指令实现的。全局变量查找是一个开销比较大的操作,包括了一系列的步骤(如果比较感兴趣的话,可以看看我之前关于属性查找方面的博文)。一旦format函数被定位到,二进制加操作(BINARY_ADD)将会被唤醒对变量a、b进行相加。最后,通过CALL_FUNCTION字节码指令调用format函数,然后将格式化后的结果返回。Python中的函数调用具有相当大的开销。当使用str.format()时,消耗在LOAD_ATTR 和 CALL_FUNCTION上额外的时间导致str.format()比F-strings慢的多。
那么%-strings 这种格式化方法又是什么原因呢?之前的结果可以看到,它的运行速度介于str.format()和F-strings之间。让我们再一次看一下使用%-strings 格式化方法反汇编后的字节码来寻找一些线索:
一瞬间,我们就发现字节码中并没有LOAD_ATTR 和 CALL_FUNCTION指令——所以 %-string 这种方法避免了全局属性查找和函数调用的开销。这解释了为什么%-strings 要比str.format()快。但为什么%-strings 的运行速度仍然比f-strings要慢呢?在BINARY_MODULO字节码指令上,%-strings 可能会消耗额外的时间。通过分析BINARY_MODULO字节码我并没得出结果,但看了CPython源代码后,我们就可以了解为什么在调用BINARY_MODULO时会产生很小的额外开销。
上图的Python源代码中可以看出,BINARY_MODULO操作是过载的。每次被调用时,它总需要检查运算对象的类型来决定元算对象是否为字符串对象(代码的第7-13行)。如果它们是,然后modulo 执行字符串格式操作。如果不是,它将执行日常的模块(返回第一个参数和第二个参数的余数)。尽管很小,但这种类型检查确实产生了一些额外开销,而F-strings并不存在这些问题。
希望这篇文章能给大家一些启发,帮助大家理解为什么F-strings能从众多字符串格式化方法中脱颖而出。F-strings快速、易学、实用,能有效减少代码量,何不快快用起来!
探索Python F-strings是如何工作的更多相关文章
- 探索 Python 学习
Python 是一种敏捷的.动态类型化的.极富表现力的开源编程语言,可以被自由地安装到多种平台上(参阅 参考资料).Python 代码是被解释的.如果您对编辑.构建和执行循环较为熟悉,则 Python ...
- 探索 Python、机器学习和 NLTK 库 开发一个应用程序,使用 Python、NLTK 和机器学习对 RSS 提要进行分类
挑战:使用机器学习对 RSS 提要进行分类 最近,我接到一项任务,要求为客户创建一个 RSS 提要分类子系统.目标是读取几十个甚至几百个 RSS 提要,将它们的许多文章自动分类到几十个预定义的主题领域 ...
- Python网络编程04 /recv工作原理、展示收发问题、粘包现象
Python网络编程04 /recv工作原理.展示收发问题.粘包现象 目录 Python网络编程04 /recv工作原理.展示收发问题.粘包现象 1. recv工作原理 2. 展示收发问题示例 发多次 ...
- Python程序员去上海工作有多难?
我只能说,也要看你掌握的技术可以打多少分.技术熟练度跟找工作的难易程度是成正比的:你掌握得越好,找工作就越容易(难度系数越低):反之越高. Python程序员这种技术类的工作岗位,当然还是要有扎实的技 ...
- 学python+django去北京找工作,靠谱吗?
有些朋友说,自己的学习能力还可以.倾向于python加框架,如django,python本来就会一些.不太了解北京公司的情况,想知道现学的python+django在北京找到工作有多少可能性. 要想知 ...
- Android艺术开发探索第四章——View的工作原理(下)
Android艺术开发探索第四章--View的工作原理(下) 我们上篇BB了这么多,这篇就多多少少要来点实战了,上篇主席叫我多点自己的理解,那我就多点真诚,少点套路了,老司机,开车吧! 我们这一篇就扯 ...
- RMQ 字符串 F. Strings and Queries
F. Strings and Queries time limit per test 2.5 s memory limit per test 256 MB input standard input o ...
- 学Python编程能做什么工作?从事什么岗位?——这些问题你知道吗?
前言 学Python编程能做什么工作?随着人工智能发展,学习python语言的人员有更多的岗位机会,python从事的职业广泛,从游戏到AI人工智能能都可以用Python实现.除了编程,各种岗位的人都 ...
- python 3和python 2 的不同之 f - strings
python3.6版本及以上版本才能使用 f "{}{}{}" f-string 格式化输出
随机推荐
- codeforces 85D D. Sum of Medians Vector的妙用
D. Sum of Medians Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/prob ...
- bzoj 4001 [TJOI2015]概率论 数学
4010: [HNOI2015]菜肴制作 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...
- 2015 UESTC 搜索专题E题 吴队长征婚 爆搜
吴队长征婚 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 Descri ...
- Centos7 内核从3.10升级到4.12过程
http://blog.csdn.net/youshijifen/article/details/73472434
- 个人对AutoResetEvent和ManualResetEvent的理解
一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非 ...
- js 实现纯前端将数据导出excel
通过将json遍历进行字符串拼接,将字符串输出到csv文件,输出的文件不会再是html类型的文件而是真正的csv文件,代码如下 <html> <head> <p styl ...
- Ruby:对象模型(又称八卦模型)笔记
备注 如果说哪门语言对我影响最大,那就是Ruby了,在.NET阵营多年,试图去用C#的思维去解释很多东西,当然解释Java是足够了,可惜我也用了好几年去解释Javascript,结果是可想而知的:解释 ...
- lua中遍历table的几种方式比较
当我在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: for key, value in pairs(tbtes ...
- 电子书mobi的格式详解
https://wiki.mobileread.com/wiki/MOBI#Format Like PalmDOC, the Mobipocket file format is that of a s ...
- USACO ariprog 暴力枚举+剪枝
/* ID:kevin_s1 PROG:ariprog LANG:C++ */ #include <iostream> #include <cstdio> #include & ...