浅析Python 中几种字符串格式化方法及其比较


Posted in Python onJuly 02, 2019

起步

在 Python 中,提供了很多种字符串格式化的方式,分别是 %-formatting、str.format 和 f-string 。本文将比较这几种格式化方法。

%- 格式化

这种格式化方式来自于 C 语言风格的 sprintf 形式:

name = "weapon"
"Hello, %s." % name

C 语言的给实话风格深入人心,通过 % 进行占位。

为什么 %-formatting不好

不好的地方在于,如果字符串较长或较多的参数,那么可读性就变得很差。

str.format 格式化

PEP-3101 带来了 str.format ,它是对 %-formatting 的改进。它使用正常的函数调用语法,并且可以通过对要转换为字符串的对象的 __format __() 方法进行扩展。

"Hello, {}. You are {}.".format(name, age)

并支持字典形式传参,免于位置参数带来的麻烦:

"Hello, {name}. You are {age}.".format(name=name, age=age)

这两种方式代码效果相同,只是第一种方法需要严格控制传入的参数位置,而第二种方法没有这种限制, 并增加了代码的可读性。各种技巧可查看 Format Specification Mini-Language

为什么 str.format() 并不好

虽然它解决了字符串冗长情况下的可读性,但需要对字典传参基本是要重写一遍变量名,不够优雅。

f-string 格式化

PEP-0498 带来了 f-string 方式,它从 Python3.6 开始支持。这种方式也是使用 __format__ 协议进行格式化。

name = "Eric"
age = 74
f"Hello, {name}. You are {age}."

语法上与 str.format() 类似,但更为简洁,当字符串较长时也不会繁琐。更强大的是它支持任意的表达式。我们可以在花括号内进行四则运算或函数调用等:f"{2 * 6}" 或者 f"{name.lower()} is funny"

并且它性能也最好。

几种格式化方式性能比较

import timeit
def add():
  status = 200
  body = 'hello world'
  return 'Status: ' + str(status) + '\r\n' + body + '\r\n'
def old_style():
  status = 200
  body = 'hello world'
  return 'Status: %s\r\n%s\r\n' % (status, body)
def formatter1():
  status = 200
  body = 'hello world'
  return 'Status: {}\r\n{}\r\n'.format(status, body)
def formatter2():
  status = 200
  body = 'hello world'
  return 'Status: {status}\r\n{body}\r\n'.format(status=status, body=body)
def f_string():
  status = 200
  body = 'hello world'
  return f'Status: {status}\r\n{body}\r\n'
perf_dict = {
  'add': min(timeit.repeat(lambda: add())),
  'old_style': min(timeit.repeat(lambda: old_style())),
  'formatter1': min(timeit.repeat(lambda: formatter1())),
  'formatter2': min(timeit.repeat(lambda: formatter2())),
  'f_string': min(timeit.repeat(lambda: f_string())),
}
print(perf_dict)

结果:

{
  'add': 0.8815229000000002, 
  'old_style': 0.6351808999999999, 
  'formatter1': 0.7536176999999995, 
  'formatter2': 1.2277180999999997, 
  'f_string': 0.4891379000000011
}

f-string 格式化的方式性能最好。

为何 f-string 速度如此快

从指令来看,f'Status: {status}\r\n{body}\r\n' 翻译成:

8 LOAD_CONST        3 ('Status: ')
10 LOAD_FAST        0 (status)
12 FORMAT_VALUE       0
14 LOAD_CONST        4 ('\r\n')
16 LOAD_FAST        1 (body)
18 FORMAT_VALUE       0
20 LOAD_CONST        4 ('\r\n')
22 BUILD_STRING       5

正如指令中所示的,f-string 是运行时渲染的,底层中转成了类似 "Status: " + status+ "\r\n" + body + "\r\n" 的形式。正如 PEP-0498 中提到的:

F-strings provide a way to embed expressions inside string literals, using a minimal syntax. It should be noted that an f-string is really an expression evaluated at run time, not a constant value. In Python source code, an f-string is a literal string, prefixed with 'f', which contains expressions inside braces. The expressions are replaced with their values.

而其他方式则是要先创建字符串常量值,再进行替换之类的操作。

总结

我们仍然可以使用以前的方式进行格式化,但在此推荐 f-string 方式,因为它使用更简洁,更易读且更方便,性能又更好,完全没理由拒绝啊。

从今天开始使用 f-string!

以上所述是小编给大家介绍的Python 中几种字符串格式化方法及其比较,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
如何使用python爬取csdn博客访问量
Feb 14 Python
Python基于二分查找实现求整数平方根的方法
May 12 Python
用tensorflow构建线性回归模型的示例代码
Mar 05 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
Apr 11 Python
django框架事务处理小结【ORM 事务及raw sql,customize sql 事务处理】
Jun 27 Python
Python实现个人微信号自动监控告警的示例
Jul 03 Python
python3实现斐波那契数列(4种方法)
Jul 15 Python
Python实现图片添加文字
Nov 26 Python
在tensorflow实现直接读取网络的参数(weight and bias)的值
Jun 24 Python
python 实现汉诺塔游戏
Nov 28 Python
细说NumPy数组的四种乘法的使用
Dec 18 Python
Python网络编程之ZeroMQ知识总结
Apr 25 Python
Python实用工具FuckIt.py介绍
Jul 02 #Python
Python如何实现转换URL详解
Jul 02 #Python
Pandas的read_csv函数参数分析详解
Jul 02 #Python
如何使用Python实现斐波那契数列
Jul 02 #Python
pandas数据筛选和csv操作的实现方法
Jul 02 #Python
Python列表与元组的异同详解
Jul 02 #Python
Pandas中resample方法详解
Jul 02 #Python
You might like
动态网站web开发 PHP、ASP还是ASP.NET
2006/10/09 PHP
Ajax和PHP正则表达式验证表单及验证码
2016/09/24 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
PHP+Session防止表单重复提交的解决方法
2018/04/09 PHP
在javascript中关于节点内容加强
2013/04/11 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
2013/12/12 Javascript
谈谈对offsetleft兼容性的理解
2015/11/11 Javascript
jquery制做精致的倒计时特效
2016/06/13 Javascript
JSON字符串和JSON对象相互转化实例详解
2017/01/05 Javascript
vue-prop父组件向子组件进行传值的方法
2018/03/01 Javascript
Electron中实现大文件上传和断点续传功能
2018/10/28 Javascript
利用Angular2的Observables实现交互控制的方法
2018/12/27 Javascript
vue+elementUI实现表格关键字筛选高亮
2020/10/26 Javascript
Vue的路由及路由钩子函数的实现
2019/07/02 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
2019/08/20 Javascript
vue radio单选框,获取当前项(每一项)的value值操作
2020/09/10 Javascript
js实现随机点名功能
2020/12/23 Javascript
使用优化器来提升Python程序的执行效率的教程
2015/04/02 Python
Python错误: SyntaxError: Non-ASCII character解决办法
2017/06/08 Python
python入门教程 python入门神图一张
2018/03/05 Python
Django开发中复选框用法示例
2018/03/20 Python
django将图片上传数据库后在前端显式的方法
2018/05/25 Python
Python查看微信撤回消息代码
2018/06/07 Python
python实现图片批量压缩程序
2018/07/23 Python
[原创]Python入门教程5. 字典基本操作【定义、运算、常用函数】
2018/11/01 Python
pandas计数 value_counts()的使用
2019/06/24 Python
15个Pythonic的代码示例(值得收藏)
2020/10/29 Python
落实八项规定专题民主生活会对照检查材料
2014/09/15 职场文书
2014年财务经理工作总结
2014/12/08 职场文书
2014年标准化工作总结
2014/12/17 职场文书
放飞理想主题班会
2015/08/14 职场文书
企业团队精神心得体会
2016/01/19 职场文书
2019公司借款合同范本2篇!
2019/07/24 职场文书
2020年基层司法所建设情况调研报告
2019/11/30 职场文书
Python爬虫之自动爬取某车之家各车销售数据
2021/06/02 Python