浅析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 Web框架Tornado运行和部署
Oct 19 Python
Python中取整的几种方法小结
Jan 06 Python
python僵尸进程产生的原因
Jul 21 Python
python实现淘宝秒杀聚划算抢购自动提醒源码
Jun 23 Python
python基础教程项目二之画幅好画
Apr 02 Python
python实现将一个数组逆序输出的方法
Jun 25 Python
pytorch打印网络结构的实例
Aug 19 Python
基于python3生成标签云代码解析
Feb 18 Python
Python绘制动态水球图过程详解
Jun 03 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
Jun 27 Python
python定义具名元组实例操作
Feb 28 Python
详解如何用Python实现感知器算法
Jun 18 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 flush类输出缓冲剖析
2008/10/19 PHP
php cookies中删除的一般赋值方法
2011/05/07 PHP
php不用正则验证真假身份证
2013/11/06 PHP
php过滤html中的其他网站链接的方法(域名白名单功能)
2014/04/24 PHP
PHP获取链表中倒数第K个节点的方法
2018/01/18 PHP
防止网站内容被拷贝的一些方法与优缺点好处与坏处分析
2007/11/30 Javascript
让你的CSS像Jquery一样做筛选的实现方法
2011/07/10 Javascript
JQuery实现简单时尚快捷的气泡提示插件
2012/12/20 Javascript
javascript中call和apply方法浅谈
2013/09/27 Javascript
JavaScript比较两个对象是否相等的方法
2015/02/06 Javascript
js简单实现点击左右运动的方法
2015/04/10 Javascript
jQuery实现的简洁下拉菜单导航效果代码
2015/08/26 Javascript
jQuery Dialog对话框事件用法实例分析
2016/05/10 Javascript
详解JS数据类型的值拷贝函数(深拷贝)
2017/07/13 Javascript
jQuery Ajax 实现分页 kkpager插件实例代码
2017/08/10 jQuery
JS实现简单的文字无缝上下滚动功能示例
2019/06/22 Javascript
vue中使用vue-pdf的方法详解
2020/09/05 Javascript
jquery实现穿梭框功能
2021/01/19 jQuery
python基础教程之字典操作详解
2014/03/25 Python
python在指定目录下查找gif文件的方法
2015/05/04 Python
举例讲解Python设计模式编程的代理模式与抽象工厂模式
2016/01/16 Python
python sys.argv[]用法实例详解
2018/05/25 Python
python使用matplotlib模块绘制多条折线图、散点图
2020/04/26 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
python破解bilibili滑动验证码登录功能
2019/09/11 Python
使用PyCharm进行远程开发和调试的实现
2019/11/04 Python
Python实现序列化及csv文件读取
2020/01/19 Python
python 在threading中如何处理主进程和子线程的关系
2020/04/25 Python
python实现视频压缩功能
2020/12/18 Python
html5组织文档结构_动力节点Java学院整理
2017/07/11 HTML / CSS
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
行政人员岗位职责
2013/12/08 职场文书
家长建议怎么写
2014/05/15 职场文书
学雷锋志愿者活动总结
2014/06/27 职场文书
征用土地赔偿协议书
2014/09/26 职场文书
正风肃纪剖析材料范文
2014/10/10 职场文书