浅析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删除特定文件的方法
Jul 30 Python
python编写分类决策树的代码
Dec 21 Python
Python基于高斯消元法计算线性方程组示例
Jan 17 Python
Python 判断 有向图 是否有环的实例讲解
Feb 01 Python
对python打乱数据集中X,y标签对的方法详解
Dec 14 Python
解决使用PyCharm时无法启动控制台的问题
Jan 19 Python
Linux上使用Python统计每天的键盘输入次数
Apr 17 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
Oct 11 Python
python GUI库图形界面开发之PyQt5访问系统剪切板QClipboard类详细使用方法与实例
Feb 27 Python
基于pandas向csv添加新的行和列
May 25 Python
Python reversed反转序列并生成可迭代对象
Oct 22 Python
python 中的jieba分词库
Nov 23 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的QRcode类与大家分享
2011/11/13 PHP
PHP 7.1新特性的汇总介绍
2016/12/16 PHP
PHP添加文字水印或图片水印的水印类完整源代码与使用示例
2019/03/18 PHP
Thinkphp5框架实现图片、音频和视频文件的上传功能详解
2019/08/27 PHP
jquery 弹出登录窗口实现代码
2009/12/24 Javascript
javascript 同时在IE和FireFox获取KeyCode的代码
2010/02/07 Javascript
FileUpload上传图片(图片不变形)
2010/08/05 Javascript
Javascript基础知识(二)事件
2014/09/29 Javascript
详解jQuery简单的表格应用
2016/12/16 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
2017/04/11 Javascript
小程序实现列表点赞功能
2018/11/02 Javascript
Vue表情输入组件 微信face表情组件
2019/02/11 Javascript
详解iframe跨域的几种常用方法(小结)
2019/04/29 Javascript
24个解决实际问题的ES6代码片段(小结)
2020/02/02 Javascript
vue+elementUI中表格高亮或字体颜色改变操作
2020/11/02 Javascript
[03:26]回顾2015国际邀请赛中国区预选赛
2015/06/09 DOTA
[01:54]TI珍贵瞬间系列(三):翻盘
2020/08/28 DOTA
Python实现删除当前目录下除当前脚本以外的文件和文件夹实例
2015/07/27 Python
Eclipse中Python开发环境搭建简单教程
2016/03/23 Python
Python使用正则表达式过滤或替换HTML标签的方法详解
2017/09/25 Python
python实现12306抢票及自动邮件发送提醒付款功能
2018/03/08 Python
java中两个byte数组实现合并的示例
2018/05/09 Python
Python字典循环添加一键多值的用法实例
2019/01/20 Python
梅尔频率倒谱系数(mfcc)及Python实现
2019/06/18 Python
python实现简单日志记录库glog的使用
2019/12/13 Python
基于keras 模型、结构、权重保存的实现
2020/01/24 Python
python+opencv实现移动侦测(帧差法)
2020/03/20 Python
浅析python函数式编程
2020/09/26 Python
三星俄罗斯授权在线商店:Samsung俄罗斯
2019/09/28 全球购物
工程管理英文求职信
2014/03/18 职场文书
竞聘演讲稿怎么写
2014/08/28 职场文书
幸福中国演讲稿
2014/09/12 职场文书
狮子林导游词
2015/02/03 职场文书
百年孤独读书笔记
2015/06/29 职场文书
如何正确理解python装饰器
2021/06/15 Python
GoFrame基于性能测试得知grpool使用场景
2022/06/21 Golang