Python语法分析之字符串格式化


Posted in Python onJune 13, 2019

前序

There should be one - and preferably only one - obvious way to do it.
———— the Zen of Python
意译:Python提倡用一种,而且最好是只有一种方法来完成一件事

虽然 Python 有以上的提倡,但却在字符串格式化方面,没有做到这一点。

字符串格式化

敲黑板,划重点:在 Python 中有至少三种常见方式实现字符串格式化:

  1. %-formatting 格式(Python2.6以前,推荐输出时使用)
  2. str.format() 格式(Python2.6,推荐字符串拼接使用)
  3. f-string 格式(Python3.6,推荐使用)

1、printf 风格的字符串格式化(%-formatting 格式)

Python2.6 之前只有这一种方式,使用与 C 中 printf 函数一样的语法。

基础语法:format % value(其中 format 为一个字符串),在 format 中的 % 转换标记符将被替换为零个或者多个 value 条目

基础用法

# coding in Python3.7
print('this is %s blog written in %d%%%02d%%%d %02d:%d:%06.2f' 
  % ('TinyDolphin', 2019, 5, 31, 9, 30, 22.3333))
# this is TinyDolphin blog written in 2019%05%31 09:30:022.33

print('title=%(title)s, author=%(name)s' 
  % {'name': 'TinyDolphin', 'title': 'Python 语法浅析:字符串格式化'})
# title=Python 语法浅析:字符串格式化, author=TinyDolphin

print('%0*.*f' % (6, 2, 2.345))
# 002.35

printf 语法

针对这种格式化操作,重要知识点如下:

1、针对这些转换标记字符,必须按照以下顺序:

    % --> (name) --> '#'、'-'、'0'、'+'、' ' --> m.n | m --> d、s、r、f

2、常用转换类型:

  • %s 格式化字符串(str()函数)
  • %r 格式化字符串(repr()函数)
  •  %d 格式化整数
  • %f 格式化浮点数字,可指定小数点后的精度

3、常用的转换标记字符:

  •  - 用做左对齐
  • + 在正数前面显示加号( + )
  • # 在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')
  • 0 显示的数字前面填充'0',而不是默认的空格
  • % '%%'输出一个单一的'%'
  •  m.n 表示 m 是显示的最小总宽度,n 是小数点后的位数
  •  * 定义宽度或者小数点精度(用在不能预先指定m.n的值)
  •  (var) 映射变量(字典参数)

2、字符串的方式(str.format()格式)

Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能,比如:支持位置映射、关键字映射、对象属性映射、下标映射等多种方式

基本语法是通过 {} 和 : 来代替以前的 %,例如:'%03.2f'被改写成 '{:03.2f}'。

两个格式化方法:

str.format(*args, **kwargs)
    字符串的格式化操作。
    str 包含字符串字面值 AND {} 括起来的替换域。
    每个替换域:位置参数的索引 OR 关键字参数的名称
   
str.format_map(mapping)
    类似于 str.foramt(**mapping)
    不同之处:mapping 会被直接使用而不是复制到一个dict。

PS:Python 存在内置函数 format(value, format_spec):会转换成 type(value).format(value, format_spec)

基础用法

1、按位置访问参数

'{0}-{1}-{2}'.format('a', 'b', 'c')   # 'a-b-c'
'{}-{}-{}'.format('a', 'b', 'c')    # 'a-b-c'
'{2}-{1}-{0}'.format('a', 'b', 'c')   # 'c-b-a'
'{2}-{1}-{0}'.format(*'abc')      # 'c-b-a'

args = ['a', 'b', 'c']
'{2}-{1}-{0}'.format(*args)       # 'c-b-a'

'{0}-{1}-{0}'.format(*['abc', 'def'])  # 'abc-def-abc'

2、按名称访问参数

'{a}-{b}'.format(a='1', b='2')     # '1-2'

kwargs = {'a':'1', 'b':'2'}
'{a}-{b}'.format(**kwargs)       # '1-2'

3、访问参数的属性

class Point:
  def __init__(self, x, y):
    self.x, self.y = x, y
  def __str__(self):
    return 'Point({self.x}, {self.y})'.format(self=self)
    
str(Point(3, 4))            # 'Point(3, 4)'

4、访问参数的项

point = (3, 5)
'X:{0[0]} Y:{0[1]}'.format(point)    # 'X:3 Y:5'

5、替代 %s 和 %r (!s、!r)

'str() = {!s}; repr() = {!r}'.format('a', 'a') # "str() = a; repr() = 'a'"

6、对齐文本以及制定宽度(:<、:^、:>)

'{:<20}'.format('left aligned')     # 'left aligned    '
'{:>20}'.format('right aligned')    # '    right aligned'
'{:^20}'.format('centered')       # '   centered   '
# 使用 '*' 作为填充字符
'{:*^20}'.format('centered')      # '******centered******'

7、替代 %+f、%-f 和 %f 以及指定正负号(:+、:-、:)

'{:+f} {:+f}'.format(3.14, -3.14)    # '+3.140000 -3.140000'
'{: f} {: f}'.format(3.14, -3.14)    # ' 3.140000 -3.140000' 正号—>空格
'{:-f} {:-f}'.format(3.14, -3.14)    # '3.140000 -3.140000' == '{:f} {:f}'

8、替换 %x 和 %o 以及转换基于不同进位制的值(:x、:d、:o、:b)

'int:{0:d} hex:{0:x} oct:{0:o} bin:{0:b}'.format(42)
# 'int:42 hex:2a oct:52 bin:101010'
'int:{0:d} hex:{0:#x} oct:{0:#o} bin:{0:#b}'.format(42)
# 'int:42 hex:0x2a oct:0o52 bin:0b101010'
# '#' : 加上前缀:0x、0o、0b

9、使用逗号作为千位分隔符(:,)

'{:,}'.format(123456789)        # '123,456,789'

10、表示为百分数(:.2%)

'{:.2%}'.format(19/22)         # '86.36%'

11、使用特定类型的专属格式化

import datetime
d = datetime.datetime(2019, 6, 10, 22, 5, 13)
'{:%Y-%m-%d %H:%M:%S}'.format(d)
# '2019-06-10 22:05:13'

12、嵌套参数以及更复杂的示例


3、格式化字符串字面值(f-string 格式)

是带有 'f' 或 'F' 前缀的字符串字面值。

花括号以外的部分按其字面值处理,除了双重花括号 '{{' 或 '}}' 会被替换为相应的单个花括号。

语法如下:

单个花括号 '{',标示一个替换字段(以 Python 表达式打头)
 + 可能有一个以叹号 '!' 标示的转换字符
 + 可能有一个以冒号 ':' 标示的格式说明符
 + 以一个右花括号 '}' 作为结束

注意:格式化字符串字面值中的表达式:

  • 当作正常的 Python 表达式处理 (这一点很重要,也很强大)
  • 不允许空表达式
  • lambda 表达式必须显式地加上圆括号
  • 可以包含换行(例如三引号字符串中)
  • 不能包含注释
  • 从左到右被求值

如果指定了转换符,则表达式求值的结果会先转换再格式化。之后使用 Python 内置函数 format() 进行格式化。

基本用法

name = 'tinyDolphin'
f'my name is {name}'      # 'my name is tinyDolphin'
f'my name is {name!r}'     # "my name is 'tinyDolphin'"

width = 10
precision = 4
value = 12.34567
f'{value:{width}.{precision}}' # '   12.35'

today = datetime.datetime(year=2019, month=6, day=10)
f'{today:%B %d, %Y}'      # 'June 10, 2019'

number = 1024
f'{number:#0x}'         # '0x400'

PS:与 str.format() 有一点不同:在 str.format() 中,非数字索引将自动转化为字符串,而f-strings则不会。

kwargs = {'a':1, 'b':2}
# 使用 str.format()
'a={kwargs[a]}'.format(kwargs=kwargs)  # 'a=1'

# 使用 f-string
f"a={kwargs[a]}"            # × 发生异常
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

# 正确使用 f-string
f"a={kwargs['a']}"           # 'a=1'

总结

从以下三个方面进行对比:

速度上:f-string > %-formatting > str.format()
功能上:f-string > str.format() > %-formatting
可读性: f-string > str.format() > %-formatting

对于速度验证,笔者就不在此进行验证了。

推荐使用场景:

%-formatting:Python2 中,由于其性能优势,在涉及输出的一些操作时,优先推荐使用
str.format():Python2 中,由于其功能优势,在涉及字符串拼接的一些操作时,优先推荐使用
f-string:    Python3 中,强烈推荐使用

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
使用Python脚本在Linux下实现部分Bash Shell的教程
Apr 17 Python
python列表操作之extend和append的区别实例分析
Jul 28 Python
编写Python脚本抓取网络小说来制作自己的阅读器
Aug 20 Python
Python编程实现的图片识别功能示例
Aug 03 Python
Python内存读写操作示例
Jul 18 Python
在python image 中安装中文字体的实现方法
Aug 22 Python
Python利用Scrapy框架爬取豆瓣电影示例
Jan 17 Python
基于Tensorflow使用CPU而不用GPU问题的解决
Feb 07 Python
Python使用docx模块实现刷题功能代码
Feb 13 Python
python实现按键精灵找色点击功能教程,使用pywin32和Pillow库
Jun 04 Python
pytorch掉坑记录:model.eval的作用说明
Jun 23 Python
python读取pdf格式文档的实现代码
Apr 01 Python
pyqt5 从本地选择图片 并显示在label上的实例
Jun 13 #Python
通过pycharm使用git的步骤(图文详解)
Jun 13 #Python
Windows 安装 Anaconda3+PyCharm的方法步骤
Jun 13 #Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
Jun 13 #Python
在Pycharm中使用GitHub的方法步骤
Jun 13 #Python
python 实现在tkinter中动态显示label图片的方法
Jun 13 #Python
windows10下安装TensorFlow Object Detection API的步骤
Jun 13 #Python
You might like
Banner程序
2006/10/09 PHP
使用PHP静态变量当缓存的方法
2013/11/13 PHP
PHP模块memcached使用指南
2014/12/08 PHP
推荐10个提供免费PHP脚本下载的网站
2014/12/31 PHP
PHP Warning: Module 'modulename' already loaded in问题解决办法
2015/03/16 PHP
php动态生成缩略图并输出显示的方法
2015/04/20 PHP
CodeIgniter中使用Smarty3基本配置
2015/06/29 PHP
浅谈Laravel队列实现原理解决问题记录
2017/08/19 PHP
利用Laravel生成Gravatar头像地址的优雅方法
2017/12/30 PHP
javascript 获取图片颜色
2009/04/05 Javascript
Google 静态地图API实现代码
2010/11/19 Javascript
javascript之querySelector和querySelectorAll使用说明
2011/10/09 Javascript
深入理解javascript中return的作用
2013/12/30 Javascript
Array 重排序方法和操作方法的简单实例
2014/01/24 Javascript
JS实现网页上随滚动条滚动的层效果代码
2015/11/04 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
简单理解Vue中的nextTick方法
2018/01/30 Javascript
快速处理vue渲染前的显示问题
2018/03/05 Javascript
vue.js element-ui tree树形控件改iview的方法
2018/03/29 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
详解vue 组件的实现原理
2020/11/12 Javascript
[01:45:05]VGJ.T vs Newbee Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
python基础教程之字典操作详解
2014/03/25 Python
python登陆asp网站页面的实现代码
2015/01/14 Python
python实现给微信公众号发送消息的方法
2017/06/30 Python
基于Python Numpy的数组array和矩阵matrix详解
2018/04/04 Python
Python连接Redis的基本配置方法
2018/09/13 Python
pandas 对日期类型数据的处理方法详解
2019/08/08 Python
python根据用户需求输入想爬取的内容及页数爬取图片方法详解
2020/08/03 Python
通往英国高街的商店橱窗:Down Your High Street
2020/07/19 全球购物
ASP.NET中的身份验证有那些
2012/07/13 面试题
挑战杯创业计划书的写作指南
2014/01/07 职场文书
信用社员工先进事迹材料
2014/02/04 职场文书
年度考核登记表个人总结
2015/03/06 职场文书
煤矿安全生产工作总结
2015/08/13 职场文书
使用opencv-python如何打开USB或者笔记本前置摄像头
2022/06/21 Python