浅析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技能之数据导出excel的实例代码
Aug 11 Python
定制FileField中的上传文件名称实例
Aug 23 Python
Django中ORM表的创建和增删改查方法示例
Nov 15 Python
Python安装pycurl失败的解决方法
Oct 15 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
Apr 04 Python
pandas数据处理进阶详解
Oct 11 Python
在Python中实现函数重载的示例代码
Dec 12 Python
简单了解Python3 bytes和str类型的区别和联系
Dec 19 Python
python正则表达式实例代码
Mar 03 Python
Python loguru日志库之高效输出控制台日志和日志记录
Mar 07 Python
django前端页面下拉选择框默认值设置方式
Aug 09 Python
python函数超时自动退出的实操方法
Dec 28 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+mysql实现简单登录注册修改密码网页
2016/11/30 PHP
浅谈PHP表单提交(POST&GET&URL编/解码)
2017/04/03 PHP
php 数据结构之链表队列
2017/10/17 PHP
javascript &&和||运算法的另类使用技巧
2009/11/28 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
2012/04/07 Javascript
jQuery基础框架浅入剖析
2012/12/27 Javascript
Extjs4中的分页应用结合前后台
2013/12/13 Javascript
JS运动基础框架实例分析
2015/03/03 Javascript
使用JS中的Replace()方法遇到的问题小结
2017/10/20 Javascript
Router解决跨模块下的页面跳转示例
2018/01/11 Javascript
express.js中间件说明详解
2019/03/19 Javascript
vuejs数据超出单行显示更多,点击展开剩余数据实例
2019/05/05 Javascript
JQuery样式操作、click事件以及索引值-选项卡应用示例
2019/05/14 jQuery
微信头像地址失效踩坑记附带解决方案
2019/09/23 Javascript
JS中比较两个Object数组是否相等方法实例
2019/11/11 Javascript
深入理解Antd-Select组件的用法
2020/02/25 Javascript
用vue 实现手机触屏滑动功能
2020/05/28 Javascript
浅谈element中InfiniteScroll按需引入的一点注意事项
2020/06/05 Javascript
Python实现接受任意个数参数的函数方法
2018/04/21 Python
解决pyinstaller打包exe文件出现命令窗口一闪而过的问题
2018/10/31 Python
使用python从三个角度解决josephus问题的方法
2020/03/27 Python
解决Python在导入文件时的FileNotFoundError问题
2020/04/10 Python
Python中的wordcloud库安装问题及解决方法
2020/05/27 Python
Python Opencv实现单目标检测的示例代码
2020/09/08 Python
深入浅析CSS3中的Flex布局整理
2020/04/27 HTML / CSS
合同专员岗位职责
2013/12/18 职场文书
面试后感谢信
2014/02/01 职场文书
四年大学生活的自我评价范文
2014/02/07 职场文书
英语国培研修感言
2014/02/13 职场文书
中文教师求职信
2014/02/22 职场文书
羽毛球社团活动总结
2014/06/27 职场文书
党小组意见范文
2015/06/08 职场文书
2016年校园重阳节广播稿
2015/12/18 职场文书
《蟋蟀的住宅》教学反思
2016/02/17 职场文书
90后经典动画片排行:《数码宝贝》第二,《小鲤鱼历险记》在榜
2022/03/18 日漫
Java 通过手写分布式雪花SnowFlake生成ID方法详解
2022/04/07 Java/Android