Python中格式化字符串的四种实现


Posted in Python onMay 26, 2020

关于Python的格式化字符串,几乎所有接触过Python语言的人都知道其中一种,即使用运算符%,但对于绝大多数初学者来说也仅此而已。

因此,本文将先总结如何通过%运算符来格式化字符串,同时指出这种方式的缺点,然后带你了解Python中另外三种强大的格式化字符串的方式:str.format()、f-string以及模板字符串,并给出在何时选择何种方式的建议。

一、%运算符格式化字符串

1. 如何使用

字符串对象都有一个使用%运算符完成的?戎貌僮鳎?杀挥美锤袷交?址??W罴虻サ娜纾?/p>

In [11]: name = "Monty Python"
In [12]: "Hello, %s." % name
Out[12]: 'Hello, Monty Python.'

如果想要对一段字符串中插入多个变量进行格式化,则需要使用一个元组将待插入变量包在一起,如:

In [14]: name = "Monty Python"

In [15]: age = 100

In [16]: "Hello, %s. You are %d years old" % (name, age)
Out[16]: 'Hello, Monty Python. You are 100 years old'

2. 缺点概述

使用%运算符的方式来格式化字符串自Python语言诞生之日起就已存在,上述代码看起来也很直观易读,但是当字符串更长,待插入变量更多,则使用%来格式化字符串的可读性将急剧下降,如:

In [23]: first_name = "Eric"

In [24]: last_name = "Idle"

In [25]: age = 100

In [26]: profession = "comedian"

In [27]: affiliation = "Monty Python"

In [28]: "Hello, %s %s. You are %s. You are a %s. You were a member of %s." % (first_name, last_name, age, profession, affiliation)
Out[28]: 'Hello, Eric Idle. You are 100. You are a comedian. You were a member of Monty Python.'

上述使用%格式化字符串不仅冗长,而且容易出错,因为这种方式并不够正确显示元组或者字典。

实际上,在Python官方文档中,对于使用%运算符格式化字符串这种方式的评价也是负面的:

  • The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly).使用%格式化字符串会产生一系列异常,这些异常将引起一系列常见错误(如:无法正确显示元组和字典)。
  • Using the newerformatted string literals, the str.format() interface, ortemplate strings may help avoid these errors.
  • 使用更新的格式化字符串字面量(f-string:formatted string literals),str.format()接口或者模板字符串(template strings)可以帮助避免这些错误。

Each of these alternatives provides their own trade-offs and benefits of simplicity, flexibility, and/or extensibility.
当然,上述三种可替代的格式化字符串方式也都在简洁、灵活和可扩展方面有所取舍。

二、str.format()格式化字符串

1. 如何使用

str.format()是对使用%实现格式化字符串的一种改进。这种方式使用的语法和普通函数调用相差无几。

使用str.format(),字符串中待替换的域使用{}表示:

In [29]: name = "Eric"

In [30]: age = 100

In [31]: "Hello, {}. You are {}.".format(name, age)
Out[31]: 'Hello, Eric. You are 100.'

也可以通过索引的方式指定format()中哪一个变量和值应该填入哪一个{},如:

In [32]: name = "Eric"

In [33]: age = 100

In [34]: "Hello, {1}. You are {0}.".format(age, name)
Out[34]: 'Hello, Eric. You are 100.'

除了索引,也可以通过在{}中指定名称的方式来实现类似上述功能,如:

In [36]: name = "Eric"

In [37]: age = 100

In [38]: "Hello, {name}. You are {age}.".format(age=age, name=name)
Out[38]: 'Hello, Eric. You are 100.'

基于上面的方式,当待格式化的信息都来自一个字典时,Python中还有如下骚操作:

In [39]: person = {'name': 'Eric', 'age': 100}

In [40]: "Hello, {name}. You are {age}.".format(name=person['name'], age=person['age'])
Out[40]: 'Hello, Eric. You are 100.'

更骚的是,上面的骚操作还能利用字典拆包**进一步简化:

In [41]: person = {'name': 'Eric', 'age': 100}

In [42]: "Hello, {name}. You are {age}.".format(**person)
Out[42]: 'Hello, Eric. You are 100.'

2. 缺点概述

相较于%运算符方式,使用str.format()已经使得格式化字符串语法更加可读,但是当变量增多时,这种方式写出的程序也会显得很冗长:

In [43]: first_name = "Eric"

In [44]: last_name = "Idle"

In [45]: age = 74

In [46]: profession = "comedian"

In [47]: affiliation = "Monty Python"

In [48]: print(("Hello, {first_name} {last_name}. You are {age}. " +
  ...: "You are a {profession}. You were a member of {affiliation}.") \
  ...: .format(first_name=first_name, last_name=last_name, age=age, \
  ...: profession=profession, affiliation=affiliation))
Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.

三、f-string格式化字符串

在Python 3.6中f-string被引入(具体请见PEP 498),也被称作格式化字符串字面量(formatted string literals)。

f-string是字符串字面量,且其以字母f开头,{}中包含变量或表达式,变量或表达式将在运行(runtime)时通过使用__format__协议被替换成具体的值。

1. 如何使用

简单的f-string格式化字符串如:

In [49]: name = "Eric"

In [50]: age = 100

In [51]: f"Hello, {name}. You are {age}."
Out[51]: 'Hello, Eric. You are 100.'

如前所述,{}中除接受变量外,还接受表达式,如:

In [52]: f"{2 * 37}"
Out[52]: '74'

f-string更强大的地方在于,{}中接受函数调用:

In [53]: def to_lowercase(input):
  ...:   return input.lower()
  ...: 

In [54]: name = "Eric Idle"

In [55]: f"{to_lowercase(name)} is funny."
Out[55]: 'eric idle is funny.'

甚至,你可以对创建于类的对象使用f-string,如:

class Comedian:
  def __init__(self, first_name, last_name, age):
    self.first_name = first_name
    self.last_name = last_name
    self.age = age

  def __str__(self):
    return f"{self.first_name} {self.last_name} is {self.age}."

  def __repr__(self):
    return f"{self.first_name} {self.last_name} is {self.age}. Surprise!"


def main():
  new_comedian = Comedian("Eric", "Idle", "74")
  print(f"{new_comedian}")


if __name__ == '__main__':
  main()

上述代码的输出为:

Eric Idle is 74.

四、Template类格式化字符串

五、参考资料

[1] Python 3's f-Strings: An Improved String Formatting Syntax (Guide)
[2] Python String Formatting Best Practices

到此这篇关于Python中格式化字符串的四种实现的文章就介绍到这了,更多相关Python格式化字符串内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python网络编程学习笔记(四):域名系统
Jun 09 Python
Python中动态获取对象的属性和方法的教程
Apr 09 Python
python抓取网页中图片并保存到本地
Dec 01 Python
Python优先队列实现方法示例
Sep 21 Python
Python实现的端口扫描功能示例
Apr 08 Python
详解Django的model查询操作与查询性能优化
Oct 16 Python
利用Django提供的ModelForm增删改数据的方法
Jan 06 Python
python 为什么说eval要慎用
Mar 26 Python
python解析命令行参数的三种方法详解
Nov 29 Python
python 使用opencv 把视频分割成图片示例
Dec 12 Python
openCV提取图像中的矩形区域
Jul 21 Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
Nov 29 Python
使用tensorflow实现VGG网络,训练mnist数据集方式
May 26 #Python
浅谈Tensorflow加载Vgg预训练模型的几个注意事项
May 26 #Python
Tensorflow加载Vgg预训练模型操作
May 26 #Python
PyQt5如何将.ui文件转换为.py文件的实例代码
May 26 #Python
TensorFlow实现模型断点训练,checkpoint模型载入方式
May 26 #Python
python 日志模块 日志等级设置失效的解决方案
May 26 #Python
python3.7+selenium模拟淘宝登录功能的实现
May 26 #Python
You might like
DOTA2 玩家自创拉野攻略 特色英雄快速成长篇
2020/04/20 DOTA
drupal 代码实现URL重写
2011/05/04 PHP
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
2011/08/02 PHP
在云虚拟主机部署thinkphp5项目的步骤详解
2017/12/21 PHP
使用laravel根据用户类型来显示或隐藏字段
2019/10/17 PHP
ThinkPHP 框架实现的读取excel导入数据库操作示例
2020/04/14 PHP
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
JavaScript中的this实例分析
2011/04/28 Javascript
JavaScript高级程序设计(第3版)学习笔记11 内建js对象
2012/10/11 Javascript
js中reverse函数的用法详解
2013/12/26 Javascript
AngularJS入门心得之directive和controller通信过程
2016/01/25 Javascript
js中常用的Math方法总结
2017/01/12 Javascript
webpack处理 css\less\sass 样式的方法
2017/08/21 Javascript
详解小程序原生使用ES7 async/await语法
2018/08/06 Javascript
js实现点击展开隐藏效果(实例代码)
2018/09/28 Javascript
详解VUE Element-UI多级菜单动态渲染的组件
2019/04/25 Javascript
js实现无缝轮播图特效
2020/05/09 Javascript
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
[02:14]完美“圣”典2016风云人物:xiao8专访
2016/12/01 DOTA
Python 十六进制整数与ASCii编码字符串相互转换方法
2018/07/09 Python
django缓存配置的几种方法详解
2018/07/16 Python
pycharm的console输入实现换行的方法
2019/01/16 Python
Python和Go语言的区别总结
2019/02/20 Python
Python 实现数据结构-堆栈和队列的操作方法
2019/07/17 Python
卡骆驰新加坡官网:Crocs新加坡
2018/06/12 全球购物
自动化工程专业个人应聘自荐信
2013/09/26 职场文书
写给女生的道歉信
2014/01/08 职场文书
自荐书范文范例
2014/02/13 职场文书
应届毕业生应聘自荐信范文
2014/02/26 职场文书
股份合作协议书
2014/04/12 职场文书
中学生期中自我鉴定
2014/04/20 职场文书
国际贸易毕业生自荐书
2014/06/22 职场文书
2015年保管员工作总结
2015/04/30 职场文书
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
2021/05/18 Vue.js
通过Qt连接OpenGauss数据库的详细教程
2021/06/23 PostgreSQL
java设计模式--三种工厂模式详解
2021/07/21 Java/Android