浅析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调用java的Webservice示例
Mar 10 Python
Python urlopen()函数 示例分享
Jun 12 Python
一个计算身份证号码校验位的Python小程序
Aug 15 Python
Python和GO语言实现的消息摘要算法示例
Mar 10 Python
Python中存取文件的4种不同操作
Jul 02 Python
Python多进程原理与用法分析
Aug 21 Python
python实现ID3决策树算法
Aug 29 Python
python判断文件是否存在,不存在就创建一个的实例
Feb 18 Python
使用Python创建简单的HTTP服务器的方法步骤
Apr 26 Python
使用pytorch实现可视化中间层的结果
Dec 30 Python
完美解决keras保存好的model不能成功加载问题
Jun 11 Python
Python 快速验证代理IP是否有效的方法实现
Jul 15 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处理Json字符串解码返回NULL的解决方法
2014/09/01 PHP
使用PHP+MySql+Ajax+jQuery实现省市区三级联动功能示例
2017/09/15 PHP
PHP函数用法详解【初始化、嵌套、内置函数等】
2020/06/02 PHP
js 匿名调用实现代码
2009/06/19 Javascript
汉化英文版的Dreamweaver CS5并自动提示jquery
2010/11/25 Javascript
JavaScript中按位“异或”运算符使用介绍
2014/03/14 Javascript
JSONP跨域的原理解析及其实现介绍
2014/03/22 Javascript
一个JS函数搞定网页标题(title)闪动效果
2014/05/13 Javascript
js正则匹配出所有图片及图片地址src的方法
2015/06/08 Javascript
jQuery实现点击后标记当前菜单位置(背景高亮菜单)效果
2015/08/22 Javascript
jquery模拟实现鼠标指针停止运动事件
2016/01/12 Javascript
JS基于ocanvas插件实现的简单画板效果代码(附demo源码下载)
2016/04/05 Javascript
js实现砖头在页面拖拉效果
2020/11/20 Javascript
vue.js学习之递归组件
2016/12/13 Javascript
js Canvas实现的日历时钟案例分享
2016/12/25 Javascript
javascript 通过键名获取键盘的keyCode方法
2017/12/31 Javascript
React中常见的动画实现的几种方式
2018/01/10 Javascript
React学习笔记之高阶组件应用
2018/06/02 Javascript
jQuery实现的淡入淡出图片轮播效果示例
2018/08/29 jQuery
JS基于开关思想实现的数组去重功能【案例】
2019/02/18 Javascript
python获取beautifulphoto随机某图片代码实例
2013/12/18 Python
Python脚本实现集群检测和管理功能
2015/03/06 Python
python判断字符串是否是json格式方法分享
2017/11/07 Python
windows7 32、64位下python爬虫框架scrapy环境的搭建方法
2018/11/29 Python
python设计微型小说网站(基于Django+Bootstrap框架)
2019/07/08 Python
Python笔试面试题小结
2019/09/07 Python
Booking.com德国:预订最好的酒店和住宿
2020/02/16 全球购物
文史专业毕业生自荐信
2013/11/17 职场文书
机关门卫岗位职责
2013/12/30 职场文书
高中化学教学反思
2014/01/13 职场文书
医学生个人求职信范文
2014/02/07 职场文书
进口业务员岗位职责
2014/04/06 职场文书
单位证明范文
2015/06/18 职场文书
数学备课组工作总结
2015/08/12 职场文书
MySQL中B树索引和B+树索引的区别详解
2022/03/03 MySQL
Python if else条件语句形式详解
2022/03/24 Python