浅析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 27 Python
python中字符串前面加r的作用
Jun 04 Python
Python函数式编程指南(二):从函数开始
Jun 24 Python
Python多进程并发与多线程并发编程实例总结
Feb 08 Python
python分治法求二维数组局部峰值方法
Apr 03 Python
kaggle+mnist实现手写字体识别
Jul 26 Python
详解python播放音频的三种方法
Sep 23 Python
Python Numpy库常见用法入门教程
Jan 16 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
Feb 26 Python
python自定义函数def的应用详解
Jun 03 Python
Python截图并保存的具体实例
Jan 14 Python
利用Python将list列表写入文件并读取的方法汇总
Mar 25 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的面试题集
2006/11/19 PHP
PHPMailer邮件发送的实现代码
2013/05/04 PHP
jquery实现可拖动DIV自定义保存到数据的实例
2013/11/20 Javascript
javascript时间函数大全
2014/06/30 Javascript
window.onload使用指南
2015/09/13 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
简单讲解AngularJS的Routing路由的定义与使用
2016/03/05 Javascript
jQuery多个版本和其他js库冲突的解决方法
2016/08/11 Javascript
jQuery命名空间与闭包用法示例
2017/01/12 Javascript
select下拉框插件jquery.editable-select详解
2017/01/22 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
2018/01/25 Javascript
webstorm和.vue中es6语法报错的解决方法
2018/05/08 Javascript
Egg.js 中 AJax 上传文件获取参数的方法
2018/10/10 Javascript
vue.js基于v-for实现批量渲染 Json数组对象列表数据示例
2019/08/03 Javascript
Vue实现计算器计算效果
2020/08/17 Javascript
从Python程序中访问Java类的简单示例
2015/04/20 Python
python利用urllib实现爬取京东网站商品图片的爬虫实例
2017/08/24 Python
pandas DataFrame的修改方法(值、列、索引)
2019/08/02 Python
python调用支付宝支付接口流程
2019/08/15 Python
Python任务调度利器之APScheduler详解
2020/04/02 Python
使用Django搭建网站实现商品分页功能
2020/05/22 Python
python和c语言哪个更适合初学者
2020/06/22 Python
解决tensorflow/keras时出现数组维度不匹配问题
2020/06/29 Python
Django contrib auth authenticate函数源码解析
2020/11/12 Python
css3的transform中scale缩放详解
2014/12/08 HTML / CSS
整理HTML5中支持的URL编码与字符编码
2016/02/23 HTML / CSS
YOOX美国官方网站:全球著名的多品牌时尚网络概念店
2016/09/11 全球购物
素质教育标语
2014/06/27 职场文书
六查六看个人剖析材料
2014/10/14 职场文书
新员工试用期自我评价
2015/03/10 职场文书
酒店总经理岗位职责
2015/04/01 职场文书
初中生物教学随笔
2015/08/15 职场文书
关于Nginx中虚拟主机的一些冷门知识小结
2022/03/03 Servers
KVM基础命令详解
2022/04/30 Servers
vue项目如何打包之项目打包优化(让打包的js文件变小)
2022/04/30 Vue.js