浅析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赋值操作方法分享
Mar 23 Python
简单的编程0基础下Python入门指引
Apr 01 Python
Python脚本实现格式化css文件
Apr 08 Python
通过Python爬虫代理IP快速增加博客阅读量
Dec 14 Python
简单易懂的python环境安装教程
Jul 13 Python
Python学习笔记之if语句的使用示例
Oct 23 Python
python3.x上post发送json数据
Mar 04 Python
Python2.7环境Flask框架安装简明教程【已测试】
Jul 13 Python
Python3以GitHub为例来实现模拟登录和爬取的实例讲解
Jul 30 Python
Django contrib auth authenticate函数源码解析
Nov 12 Python
matplotlib常见函数之plt.rcParams、matshow的使用(坐标轴设置)
Jan 05 Python
Python获取百度热搜的完整代码
Apr 07 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
第一节--面向对象编程
2006/11/16 PHP
php debug 安装技巧
2011/04/30 PHP
php获取英文姓名首字母的方法
2015/07/13 PHP
Yii2语言国际化自动配置详解
2018/08/22 PHP
jquery插件开发方法(初学者)
2012/02/03 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
jquery分割字符串的方法
2015/06/24 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
2016/05/19 Javascript
javascript实现去除HTML标签的方法
2016/12/26 Javascript
Angular2 组件交互实例详解
2017/08/24 Javascript
js使用html2canvas实现屏幕截取的示例代码
2017/08/28 Javascript
nodejs创建简易web服务器与文件读写的实例
2017/09/07 NodeJs
js实现div色块碰撞
2020/01/16 Javascript
原生js+ajax分页组件
2020/01/30 Javascript
javascript使用Blob对象实现的下载文件操作示例
2020/04/18 Javascript
django简单的前后端分离的数据传输实例 axios
2020/05/18 Javascript
解决vuex数据页面刷新后初始化操作
2020/07/26 Javascript
[38:41]2014 DOTA2国际邀请赛中国区预选赛 LGD VS CNB
2014/05/22 DOTA
使用Python脚本来控制Windows Azure的简单教程
2015/04/16 Python
Python类的定义、继承及类对象使用方法简明教程
2015/05/08 Python
Python利用前序和中序遍历结果重建二叉树的方法
2016/04/27 Python
Python的装饰器用法学习笔记
2016/06/24 Python
python实现求两个字符串的最长公共子串方法
2018/07/20 Python
django框架CSRF防护原理与用法分析
2019/07/22 Python
python pandas cumsum求累计次数的用法
2019/07/29 Python
Python实现代码统计工具
2019/09/19 Python
Python3运算符常见用法分析
2020/02/14 Python
Python tkinter实现日期选择器
2021/02/22 Python
Etam俄罗斯:法国女士内衣和家居服网上商店
2019/10/30 全球购物
护士求职信
2014/07/05 职场文书
中学生学习保证书
2015/02/26 职场文书
运动会闭幕式主持词
2015/07/01 职场文书
导游词之珠海轮廓
2019/10/25 职场文书
如何用python插入独创性声明
2021/03/31 Python
Node.js实现断点续传
2021/06/23 Javascript
手把手教你导入Go语言第三方库
2021/08/04 Golang