浅析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和C语言混合编程实例
Jun 04 Python
跟老齐学Python之使用Python查询更新数据库
Nov 25 Python
总结Python中逻辑运算符的使用
May 13 Python
python常用函数详解
Sep 13 Python
python实现杨辉三角思路
Jul 14 Python
Python使用三种方法实现PCA算法
Dec 12 Python
对TensorFlow的assign赋值用法详解
Jul 30 Python
Python设计模式之外观模式实例详解
Jan 17 Python
解决Python找不到ssl模块问题 No module named _ssl的方法
Apr 29 Python
Python sorted排序方法如何实现
Mar 31 Python
Python脚本如何在bilibili中查找弹幕发送者
Jun 04 Python
Python实现byte转integer
Jun 03 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
菜鸟修复电子管记
2021/03/02 无线电
php_screw 1.5:php加密: 安装与使用详解
2013/06/20 PHP
thinkPHP5框架导出Excel文件简单操作示例
2018/08/03 PHP
使用ucenter实现多站点同步登录的讲解
2019/03/21 PHP
jquery多选项卡效果实例代码(附效果图)
2013/03/23 Javascript
点击进行复制的JS代码实例
2013/08/23 Javascript
解决Jquery向页面append新元素之后事件的绑定问题
2015/03/16 Javascript
jQuery实现根据生日计算年龄 星座 生肖
2016/11/23 Javascript
JS对象与JSON互转换、New Function()、 forEach()、DOM事件流等js开发基础小结
2017/08/10 Javascript
使用cropper.js裁剪头像的实例代码
2017/09/29 Javascript
详解Vue基于 Nuxt.js 实现服务端渲染(SSR)
2018/04/05 Javascript
vue-router中scrollBehavior的巧妙用法
2018/07/09 Javascript
使用D3.js+Vue实现一个简单的柱形图
2018/08/05 Javascript
Vue框架TypeScript装饰器使用指南小结
2019/02/18 Javascript
微信小程序调用微信支付接口的实现方法
2019/04/29 Javascript
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
2019/08/22 Javascript
layui使用label标签的方法
2019/09/14 Javascript
Vue实现购物车实例代码两则
2020/05/30 Javascript
[59:32]Liquid vs Fnatic 2019国际邀请赛淘汰赛败者组BO1 8.20.mp4
2020/07/19 DOTA
[01:14]2019完美世界城市挑战赛(秋季赛)全国总决赛精彩花絮
2020/01/08 DOTA
布同自制Python函数帮助查询小工具
2011/03/13 Python
python使用Turtle库绘制动态钟表
2018/11/19 Python
python按照多个条件排序的方法
2019/02/08 Python
python 基于TCP协议的套接字编程详解
2019/06/29 Python
浅析PyTorch中nn.Linear的使用
2019/08/18 Python
pycharm实现在虚拟环境中引入别人的项目
2020/03/09 Python
django rest framework serializers序列化实例
2020/05/13 Python
python 绘制正态曲线的示例
2020/09/24 Python
Myprotein法国官网:欧洲第一运动营养品牌
2019/03/26 全球购物
文言文形式的学生求职信
2013/12/03 职场文书
生日宴会答谢词
2014/01/09 职场文书
七一党建活动方案
2014/01/28 职场文书
中班中秋节活动反思
2014/02/18 职场文书
物控部经理职务说明书
2014/02/25 职场文书
结婚主持人致辞
2015/07/28 职场文书
css之clearfix的用法深入理解(必看篇)
2023/05/21 HTML / CSS