浅析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下singleton模式的实现方法
Jul 16 Python
Python中多线程thread与threading的实现方法
Aug 18 Python
Django查找网站项目根目录和对正则表达式的支持
Jul 15 Python
python3 pandas 读取MySQL数据和插入的实例
Apr 20 Python
Python实现对字典分别按键(key)和值(value)进行排序的方法分析
Dec 19 Python
python实现转圈打印矩阵
Mar 02 Python
局域网内python socket实现windows与linux间的消息传送
Apr 19 Python
Django url,从一个页面调到另个页面的方法
Aug 21 Python
Python中最好用的命令行参数解析工具(argparse)
Aug 23 Python
python 调试冷知识(小结)
Nov 11 Python
python创建学生成绩管理系统
Nov 22 Python
IronPython连接MySQL的方法步骤
Dec 27 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
PHP中HTTP方式下的Gzip压缩传输方法举偶
2007/02/15 PHP
php线性表顺序存储实现代码(增删查改)
2012/02/16 PHP
用Php编写注册后Email激活验证的实例代码
2013/03/11 PHP
ThinkPHP实现将本地文件打包成zip下载
2014/06/26 PHP
PHP中echo和print的区别
2014/08/28 PHP
PHP 将dataurl转成图片image方法总结
2016/10/14 PHP
javascript Array.sort() 跨浏览器下需要考虑的问题
2009/12/07 Javascript
基于jquery的获取mouse坐标插件的实现代码
2010/04/01 Javascript
一个报数游戏js版(约瑟夫环问题)
2010/08/05 Javascript
PHP abstract与interface之间的区别
2013/11/11 Javascript
javascript设计模式之工厂模式示例讲解
2014/03/04 Javascript
jQuery实现根据类型自动显示和隐藏表单
2015/03/18 Javascript
jquery获取节点名称
2015/04/26 Javascript
实现JavaScript的组成----BOM和DOM详解
2016/05/18 Javascript
AngularJS Controller作用域
2017/01/09 Javascript
关于ES6的六个小特性(二)
2017/02/20 Javascript
python中遍历文件的3个方法
2014/09/02 Python
Python实现遍历数据库并获取key的值
2015/05/17 Python
Python随机数random模块使用指南
2016/09/09 Python
Python字典实现简单的三级菜单(实例讲解)
2017/07/31 Python
python模块之paramiko实例代码
2018/01/31 Python
python DataFrame 修改列的顺序实例
2018/04/10 Python
Python paramiko模块的使用示例
2018/04/11 Python
numpy 进行数组拼接,分别在行和列上合并的实例
2018/05/08 Python
Python flask框架post接口调用示例
2019/07/03 Python
卡骆驰德国官方网站:Crocs德国
2019/03/29 全球购物
英国现代市场:ARKET
2019/04/10 全球购物
意大利自行车商店:Cingolani Bike Shop
2019/09/03 全球购物
Hotels.com拉丁美洲:从豪华酒店到经济型酒店的预定优惠和折扣
2019/12/09 全球购物
二年级数学教学反思
2014/01/21 职场文书
yy婚礼主持词
2014/03/14 职场文书
高中课前三分钟演讲稿
2014/09/13 职场文书
教育见习报告范文
2014/11/03 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书
2015最新学生自我评价范文
2015/03/03 职场文书
2015年度党员自我评价范文
2015/03/03 职场文书