f-string是格式化字符串的新语法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快!我们首先了解下可视化字符串语法的历史
1: %-formatting
最早的格式化是用%(百分号), 它这么用:
1 | In : name = 'Xiaoming' |
%符号前面使用一个字符串作为模板,模板中有标记格式的占位符号。占位符控制着显示的格式,这里用的%s
表示格式化成字符串,另外常用的是%d
(十进制整数)、%f
(浮点数)。
格式化语法也可以格式化多个变量,需要把变量用括号括起来:
1 | In : id = 123 |
另外也支持使用字典的形式:
1 | In : 'User[%(id)s]: %(name)s' % {'id': 123, 'name': 'Xiaoming'} |
这种用法一直到现在仍然被使广泛使用,但是其实它是一种不被提倡使用的语法(我初Python学习时,就提过)。主要是当要格式化的参数很多时,可读性很差,还容易出错(数错占位符的数量),也不灵活,举个例子,name这个变量要在格式化时用2次,就要传入2次。
2. str.format()
从 Python 2.6开始,新增了一种格式化字符串的函数str.format()
,基本语法是通过{}
和:
来代替以前的%
。format函数支持通过位置、关键字、对象属性和下标等多种方式使用,不仅参数可以不按顺序,也可以不用参数或者一个参数使用多次。并且可以通过对要转换为字符串的对象的__format __
方法进行扩展。
1 | In : name = 'Xiaoming' |
通过位置访问:
1 | In : '{0}, {1}, {2}'.format('a', 'b', 'c') |
通过关键字访问:
1 | In : 'Hello {name}'.format(name='Xiaoming') |
通过对象属性访问:
1 | In : from collections import namedtuple |
通过下标访问:
1 | In : coord = (3, 5) |
可以感受到format函数极大的扩展了格式化功能。但是当处理多个参数和更长的字符串时,str.format() 的内容仍然可能非常冗长,除了定义参数变量,需要把这些变量写进format方法里面。
3. f-Strings
现在好了,Python 3.6新增了f-strings,这个特性叫做字面量格式化字符串
,F字符串是开头有一个f的字符串文字,Python会计算其中的用大括号包起来的表达式,并将计算后的值替换进去。
1 | In : name = 'Xiaoming' |
如果你学过Ruby,ES6,你会非常容易接受这样的语法。另外在速度上,f-strings是三种方案中最快的:
1 | In : import timeit |
可以侧面感受到,str.format最慢,%s的稍快一点,F-string是最快的!你还有什么利用不用它?
现在我写Python 3.6以上的代码时,我已经完全不用另外2种格式化用法了。
future-fstrings
通过上面的例子,希望我们有一个共识,就是如果你的项目或者工作中使用的Python版本已经不小于3.6,f-string格式化是首选方式,不仅在保持功能强大的同时语义上更容易理解,而且性能也有较大的提升。但是不巧你用不了Python的f-strings,还有个选择,就是 future-fstrings 这个项目。它的作者也是pre-commit作者,一个pytest和tox核心开发。
在我个人电脑的Python 2.7 版本上体验一下:
1 | ❯ pip2.7 install future-fstrings |