浅析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使用marshal模块序列化实例
Sep 25 Python
Python 专题三 字符串的基础知识
Mar 19 Python
Python利用QQ邮箱发送邮件的实现方法(分享)
Jun 09 Python
Python实现excel转sqlite的方法
Jul 17 Python
Django Web开发中django-debug-toolbar的配置以及使用
May 06 Python
numpy添加新的维度:newaxis的方法
Aug 02 Python
Python当中的array数组对象实例详解
Jun 12 Python
python傅里叶变换FFT绘制频谱图
Jul 19 Python
使用Bazel编译TensorBoard教程
Feb 15 Python
Python利用逻辑回归分类实现模板
Feb 15 Python
学生如何注册Pycharm专业版以及pycharm的安装
Sep 24 Python
python使用BeautifulSoup 解析HTML
Apr 24 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
基于curl数据采集之单页面采集函数get_html的使用
2013/04/28 PHP
在laravel中使用with实现动态添加where条件
2019/10/10 PHP
基于Laravel(5.4版本)的基本增删改查操作方法
2019/10/11 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
Ucren Virtual Desktop V2.0
2006/11/07 Javascript
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
NodeJs中的VM模块详解
2015/05/06 NodeJs
简介可以自动完成UI的AngularJS工具angular-smarty
2015/06/23 Javascript
Linux下为Node.js程序配置MySQL或Oracle数据库的方法
2016/03/19 Javascript
jQuery验证插件validate使用详解
2016/05/11 Javascript
完美解决jQuery符号$与其他javascript 库、框架冲突的问题
2016/08/09 Javascript
ajax实现动态下拉框示例
2017/01/10 Javascript
详谈js中标准for循环与foreach(for in)的区别
2017/11/02 Javascript
浅谈js获取ModelAndView值的问题
2018/03/28 Javascript
JS在if中的强制类型转换方式
2018/07/15 Javascript
vue后台管理之动态加载路由的方法
2018/08/13 Javascript
Vue中遍历数组的新方法实例详解
2019/07/21 Javascript
VUE实现自身整体组件销毁的示例代码
2020/01/13 Javascript
Python 错误和异常小结
2013/10/09 Python
Python升级提示Tkinter模块找不到的解决方法
2014/08/22 Python
Python实现读写sqlite3数据库并将统计数据写入Excel的方法示例
2017/08/07 Python
Python读取本地文件并解析网页元素的方法
2018/05/21 Python
mac PyCharm添加Python解释器及添加package路径的方法
2018/10/29 Python
Django rstful登陆认证并检查session是否过期代码实例
2019/08/13 Python
使用keras和tensorflow保存为可部署的pb格式
2020/05/25 Python
美国知名的在线旅游服务网站:Priceline
2016/07/23 全球购物
goodhealth官方海外旗舰店:新西兰国民营养师
2017/12/15 全球购物
新西兰廉价汽车租赁:Snap Rentals
2018/09/14 全球购物
亚洲领先的旅游体验市场:Voyagin
2019/11/23 全球购物
JAVA程序员面试题
2012/10/03 面试题
英语老师推荐信
2014/02/26 职场文书
运动会开幕式主持词
2015/07/01 职场文书
2015国庆66周年宣传语
2015/07/14 职场文书
国家助学金受助感言
2015/08/01 职场文书
大学生党员暑假实践(活动总结)
2019/08/21 职场文书
详解MindSpore自定义模型损失函数
2021/06/30 Python