资讯专栏INFORMATION COLUMN

PyTips 0x0a - Python 字符串的格式化

luqiuwen / 1432人阅读

摘要:项目地址相信很多人在格式化字符串的时候都用的语法,提出一种更先进的格式化方法并成为的标准用来替换旧的格式化语法,从开始已经实现了这一方法其它解释器未考证。

项目地址:https://git.io/pytips

相信很多人在格式化字符串的时候都用"%s" % v的语法,PEP 3101 提出一种更先进的格式化方法 str.format() 并成为 Python 3 的标准用来替换旧的 %s 格式化语法,CPython 从 2.6 开始已经实现了这一方法(其它解释器未考证)。

format()

新的 format() 方法其实更像是一个简略版的模板引起(Template Engine),功能非常丰富,官方文档对其语法的描述如下:

"""
replacement_field ::=  "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name        ::=  arg_name ("." attribute_name | "[" element_index "]")*
arg_name          ::=  [identifier | integer]
attribute_name    ::=  identifier
element_index     ::=  integer | index_string
index_string      ::=   +
conversion        ::=  "r" | "s" | "a"
format_spec       ::=  
"""
pass # Donot output

我将其准换成铁路图的形式,(可能)更直观一些:

模板中替换变量用 {} 包围,且由 : 分为两部分,其中后半部分 format_spec 在后面会多带带讨论。前半部分有三种用法:

代表位置的数字

代表keyword的标识符

这与函数调用的参数类别是一致的:

print("{} {}".format("Hello", "World"))
# is equal to...
print("{0} {1}".format("Hello", "World"))
print("{hello} {world}".format(hello="Hello", world="World"))

print("{0}{1}{0}".format("H", "e"))
Hello World
Hello World
Hello World
HeH

除此之外,就像在0x05 函数参数与解包中提到的一样,format() 中也可以直接使用解包操作:

print("{lang}.{suffix}".format(**{"lang": "Python", "suffix": "py"}))
print("{} {}".format(*["Python", "Rocks"]))
Python.py
Python Rocks

在模板中还可以通过 .identifier[key] 的方式获取变量内的属性或值(需要注意的是 "{}{}" 相当于 "{0}{1}"):

data = {"name": "Python", "score": 100}
print("Name: {0[name]}, Score: {0[score]}".format(data)) # 不需要引号

langs = ["Python", "Ruby"]
print("{0[0]} vs {0[1]}".format(langs))

print("
====
Help(format):
 {.__doc__}".format(str.format))
Name: Python, Score: 100
Python vs Ruby

====
Help(format):
 S.format(*args, **kwargs) -> str

Return a formatted version of S, using substitutions from args and kwargs.
The substitutions are identified by braces ("{" and "}").
强制转换

可以通过 ! + r|s|a 的方式对替换的变量进行强制转换:

"{!r}" 对变量调用 repr()

"{!s}" 对变量调用 str()

"{!a}" 对变量调用 ascii()

格式

最后 : 之后的部分定义输出的样式:

align 代表对齐方向,通常要配合 width 使用,而 fill 则是填充的字符(默认为空白):

for align, text in zip("<^>", ["left", "center", "right"]):
    print("{:{fill}{align}16}".format(text, fill=align, align=align))
    
print("{:0=10}".format(100)) # = 只允许数字
left<<<<<<<<<<<<
^^^^^center^^^^^
>>>>>>>>>>>right
0000000100

同时可以看出,样式设置里面可以嵌套 {} ,但是必须通过 keyword 指定,且只能嵌套一层。

接下来是符号样式:+|-|" " 分别指定数字是否需要强制符号(其中空格是指在正数的时候不显示 + 但保留一位空格):

print("{0:+}
{1:-}
{0: }".format(3.14, -3.14))
+3.14
-3.14
 3.14

# 用于表示特殊格式的数字(二进制、十六进制等)是否需要前缀符号;, 也是用于表示数字时是否需要在千位处进行分隔;0 相当于前面的 {:0=} 右对齐并用 0 补充空位:

print("Binary: {0:b} => {0:#b}".format(3))

print("Large Number: {0:} => {0:,}".format(1.25e6))

print("Padding: {0:16} => {0:016}".format(3))
Binary: 11 => 0b11
Large Number: 1250000.0 => 1,250,000.0
Padding:                3 => 0000000000000003

最后两个就是我们熟悉的小数点精度 .n 和格式化类型了,这里仅给出一些示例,详细内容可以查阅文档:

from math import pi
print("pi = {pi:.2}, also = {pi:.7}".format(pi=pi))
pi = 3.1, also = 3.141593

Integer

for t in "b c d #o #x #X n".split():
    print("Type {0:>2} of {1} shows: {1:{t}}".format(t, 97, t=t))
Type  b of 97 shows: 1100001
Type  c of 97 shows: a
Type  d of 97 shows: 97
Type #o of 97 shows: 0o141
Type #x of 97 shows: 0x61
Type #X of 97 shows: 0X61
Type  n of 97 shows: 97

Float

for t, n in zip("eEfFgGn%", [12345, 12345, 1.3, 1.3, 1, 2, 3.14, 0.985]):
    print("Type {} shows: {:.2{t}}".format(t, n, t=t))
Type e shows: 1.23e+04
Type E shows: 1.23E+04
Type f shows: 1.30
Type F shows: 1.30
Type g shows: 1
Type G shows: 2
Type n shows: 3.1
Type % shows: 98.50%

String (default)

try:
    print("{:s}".format(123))
except:
    print("{}".format(456))
456


欢迎关注 PyHub!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37830.html

相关文章

  • PyTips 0x07 - Python 符串

    摘要:项目地址所有用过的人应该都看过下面两行错误信息这就是界的锟斤拷今天和接下来几期的内容将主要关注中的字符串字节及两者之间的相互转换。 项目地址:https://git.io/pytips 所有用过 Python (2&3)的人应该都看过下面两行错误信息: UnicodeEncodeError: ascii codec cant encode characters in position...

    go4it 评论0 收藏0
  • PyTips 0x11 - Python 时间与日期

    摘要:项目地址时间和日期可能涉及到不同的时区格式,同时又经常需要作为时间戳保存,有时候还需要进行一些加减操作,因此处理起来通常会因为方法太多而无从下手。中与时间和日期相关的标准库有个和。 项目地址:https://git.io/pytips 时间和日期可能涉及到不同的时区、格式,同时又经常需要作为时间戳保存,有时候还需要进行一些加减操作,因此处理起来通常会因为方法太多而无从下手。Python...

    2501207950 评论0 收藏0
  • PyTips 0x08 - Python 字节与字节数组

    摘要:回到对字节和字节数组的定义为了用计算机可以理解的数字描述人类使用的字符,我们需要一张数字与字符对应的表。由于和字符串一样是序列类型,字节和字节数组可用的方法也类似,这里就不一一列举了。 项目地址:https://git.io/pytips 0x07 中介绍了 Python 中的字符串类型,字符串类型是对人类友好的符号,但计算机只认识一种符号,那就是二进制(binary)数,或者说是数字...

    Leo_chen 评论0 收藏0
  • PyTips 0x16 - Python 迭代器工具

    摘要:借鉴了中的某些迭代器的构造方法,并在中实现该模块是通过实现,源代码。 项目地址:https://git.io/pytips 0x01 介绍了迭代器的概念,即定义了 __iter__() 和 __next__() 方法的对象,或者通过 yield 简化定义的可迭代对象,而在一些函数式编程语言(见 0x02 Python 中的函数式编程)中,类似的迭代器常被用于产生特定格式的列表(或序列)...

    mayaohua 评论0 收藏0
  • PyTips 0x01 - 迭代器与生成器

    摘要:项目地址迭代器与生成器迭代器与生成器是中比较常用又很容易混淆的两个概念,今天就把它们梳理一遍,并举一些常用的例子。生成器前面说到创建迭代器有种方法,其中第三种就是生成器。 项目地址:https://git.io/pytips 迭代器与生成器 迭代器(iterator)与生成器(generator)是 Python 中比较常用又很容易混淆的两个概念,今天就把它们梳理一遍,并举一些常用的例...

    chemzqm 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<