浅析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 numpy中nonzero()的用法
Apr 02 Python
Django框架之登录后自定义跳转页面的实现方法
Jul 18 Python
Python 如何提高元组的可读性
Aug 26 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
Oct 14 Python
Python求两个字符串最长公共子序列代码实例
Mar 05 Python
python中可以声明变量类型吗
Jun 18 Python
python安装读取grib库总结(推荐)
Jun 24 Python
用python进行视频剪辑
Nov 02 Python
python中复数的共轭复数知识点总结
Dec 06 Python
详解Flask开发技巧之异常处理
Jun 15 Python
Python实现查询剪贴板自动匹配信息的思路详解
Jul 09 Python
Python中的datetime包与time包包和模块详情
Feb 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下连接ftp实现文件的上传、下载、删除文件实例代码
2010/06/03 PHP
php实现用于删除整个目录的递归函数
2015/03/16 PHP
yii2超好用的日期组件和时间组件
2016/05/05 PHP
PHP children()函数讲解
2019/02/03 PHP
jquery1.9 下检测浏览器类型和版本的方法
2013/12/26 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
2015/02/17 Javascript
简单的jQuery入门指引
2015/07/28 Javascript
详解javascript遍历方式
2015/11/11 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
jQuery EasyUI datagrid在翻页以后仍能记录被选中行的实现代码
2016/08/15 Javascript
AngularJS表格详解及示例代码
2016/08/17 Javascript
超全面的javascript中变量命名规则
2017/02/09 Javascript
jQuery实现字符串全部替换的方法【推荐】
2017/03/09 Javascript
nodejs个人博客开发第二步 入口文件
2017/04/12 NodeJs
JS组件系列之MVVM组件 vue 30分钟搞定前端增删改查
2017/04/28 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
JavaScript实现离开页面前提示功能【附jQuery实现方法】
2017/09/26 jQuery
JavaScript递归函数解“汉诺塔”算法代码解析
2018/07/05 Javascript
从零使用TypeScript开发项目打包发布到npm
2020/02/14 Javascript
JavaScript 实现自己的安卓手机自动化工具脚本(推荐)
2020/05/13 Javascript
如何区分vue中的v-show 与 v-if
2020/09/08 Javascript
python监控网卡流量并使用graphite绘图的示例
2014/04/27 Python
python开发之tkinter实现图形随鼠标移动的方法
2015/11/11 Python
Python对接 xray 和微信实现自动告警
2019/09/17 Python
pytorch的梯度计算以及backward方法详解
2020/01/10 Python
python3读取autocad图形文件.py实例
2020/06/05 Python
Python中如何添加自定义模块
2020/06/09 Python
彪马荷兰官网:PUMA荷兰
2019/05/08 全球购物
Mountain Warehouse波兰官方网站:英国户外品牌
2019/08/29 全球购物
会计主管岗位职责范文
2013/11/08 职场文书
旅游节目策划方案
2014/05/26 职场文书
工程质检员岗位职责
2015/04/08 职场文书
工作态度怎么写
2015/06/25 职场文书
教师节班会主持词
2015/07/06 职场文书
2016年优秀少先队员事迹材料
2016/02/26 职场文书
nginx 反向代理之 proxy_pass的实现
2021/03/31 Servers