Python:% 和 .format() 的使用

多年来,Python 具有出色的字符串格式化程序,但是有关它们的文档在理论和技术上都太过严格了。通过此站点,我们尝试通过实际示例向您展示新旧风格的字符串格式化 API 涵盖的最常见的用例。

此页面上的所有示例均可与 Python 2.7、3.2、3.3、3.4 和 3.5 一起使用,而无需任何额外的库。

基本的格式化

简单的位置格式化可能是最常见的用例。如果参数的顺序不太可能改变,并且只有很少的元素要连接,可以采用这样的格式化风格。

由于元素没有像名称一样具有描述性,因此这个简单的风格仅应用于格式化相对少量的元素。

Old'%s %s' % ('one', 'two')
New'{} {}'.format('one', 'two')
Outputone two
Old'%d %d' % (1, 2)
New'{} {}'.format(1, 2)
Output1 2

使用新的格式化风格(在 Python 2.6 中甚至是强制性的),可以为占位符提供显式的位置索引。

这允许在不更改参数的情况下重新排列显示顺序。

此操作不适用于旧的格式化风格。

New'{1} {0}'.format('one', 'two')
Outputtwo one

值转换

新的简单格式化器默认调用对象的 __format__() 方法来呈现它。如果你只想呈现 str(…) 或 repr(…) 的输出,你可以使用 !s 或 !r 转换标志。

class Data(object):

    def __str__(self):
        return 'str'

    def __repr__(self):
        return 'repr'
Old'%s %r' % (Data(), Data())
New{0!s} {0!r}'.format(Data())
Outputstr repr

在 Python 3 中,存在一个附加的转换标志,该标志使用 repr(…) 的输出,但使用 ascii(…) 代替。

class Data(object):

    def __repr__(self):
        return 'räpr'
Old'%r %a' % (Data(), Data())
New'{0!r} {0!a}'.format(Data())
Outputräpr r\xe4pr

填充和对齐字符串

默认情况下,将值格式化为仅表示内容所需的字符。但是,也可以将值填充到特定的长度。

不幸的是,新旧格式化风格之间的默认对齐方式有所不同。旧风格的默认为右对齐,而新风格的则为左对齐。

右对齐:

Old'%10s' % ('test',)
New'{:>10}'.format('test')
Output      test

左对齐:

Old'%-10s' % ('test',)
New'{:10}'.format('test')
Outputtest      

同样,通过提供对值的填充和对齐方式的更多控制,新的格式化风格超越了旧的。

你可以选择填充字符:

此操作不适用于旧的格式化风格。

New'{:_<10}'.format('test')
Outputtest______

还可以居中对齐值:

此操作不适用于旧的格式化风格。

New'{:^10}'.format('test')
Output   test   

当使用居中对齐时,如果字符串的长度导致填充字符的不均匀分割,则多余的字符将被放在右侧:

此操作不适用于旧的格式化风格。

New'{:^6}'.format('zip')
Output zip  

截断长串

与填充相反,也可以将过长的值截断成特定数量的字符。

在格式字符串中点 (.) 后面的数字指定了输出的精度。对于字符串,这意味着输出将被截断为指定的长度。在示例中,这是 5 个字符。

Old'%.5s' % ('xylophone',)
New'{:.5}'.format('xylophone')
Outputxylop

结合截断与填充

Old'%-10.5s' % ('xylophone',)
New'{:10.5}'.format('xylophone')
Outputxylop     

数字

当然,也可以格式化数字。

整数:

Old'%d' % (42,)
New'{:d}'.format(42)
Output42

浮点数:

Old'%f' % (3.141592653589793,)
New'{:f}'.format(3.141592653589793)
Output3.141593

填充数字

与字符串相似,数字也可以被限制为特定的宽度。

Old'%4d' % (42,)
New'{:4d}'.format(42)
Output  42

同样,类似于截断字符串,浮点数的精度限制了小数点后的位数。

对于浮点数,填充值表示完整输出的长度。在下面的示例中,我们希望输出至少有 6 个字符,包括小数点后的 2 个字符。

Old'%06.2f' % (3.141592653589793,)
New'{:06.2f}'.format(3.141592653589793)
Output003.14

对于整数值,提供精度没有多大意义,实际上在新的风格中是被禁止的(这将导致 ValueError)。

Old'%04d' % (42,)
New'{:04d}'.format(42)
Output0042

带符号的数字

默认情况下,只有负数带有符号。这当然可以更改。

Old'%+d' % (42,)
New'{:+d}'.format(42)
Output+42

使用空格字符表示负数应以减号开头,正数应以前导空格开头。

Old'% d' % ((- 23),)
New'{: d}'.format((- 23))
Output-23
Old'% d' % (42,)
New'{: d}'.format(42)
Output 42

新的格式化风格还能够控制符号相对于填充字符的位置。

此操作不适用于旧的格式化风格。

New'{:=5d}'.format((- 23))
Output-  23
New'{:=+5d}'.format(23)
Output+  23

有名字的占位符

两种格式化风格都支持有名字的占位符。

data = {'first': 'Hodor', 'last': 'Hodor!'}
Old'%(first)s %(last)s' % data
New'{first} {last}'.format(**data)
OutputHodor Hodor!

.format() 也接受关键字参数(keyword arguments)。

此操作不适用于旧的格式化风格。

New'{first} {last}'.format(first='Hodor', last='Hodor!')
OutputHodor Hodor!

Getitem 和 Getattr

新的格式化风格在访问嵌套的数据结构时提供了更大的灵活性。

它支持访问支持 __getitem__ 的容器,例如字典和列表:

此操作不适用于旧的格式化风格。

person = {'first': 'Jean-Luc', 'last': 'Picard'}
New'{p[first]} {p[last]}'.format(p=person)
OutputJean-Luc Picard
data = [4, 8, 15, 16, 23, 42]
New'{d[4]} {d[5]}'.format(d=data)
Output23 42

以及通过 getattr() 访问对象的属性:

此操作不适用于旧的格式化风格。

class Plant(object):
    type = 'tree'
New'{p.type}'.format(p=Plant())
Outputtree

两种类型的访问都可以自由混合和任意嵌套:

此操作不适用于旧的格式化风格。

class Plant(object):
    type = 'tree'
    kinds = [{'name': 'oak'}, {'name': 'maple'}]
New'{p.type}: {p.kinds[0][name]}'.format(p=Plant())
Outputtree: oak

日期时间

新的格式化风格还允许对象控制自己的呈现。例如,这允许在格式字符串中将日期时间对象格式化:

此操作不适用于旧的格式化风格。

from datetime import datetime
New'{:%Y-%m-%d %H:%M}'.format(datetime(2001, 2, 3, 4, 5))
Output2001-02-03 04:05

参数化的格式

此外,新的格式化风格允许使用参数动态地指定格式字符串的所有组成部分。参数化的格式字符串是括号中的嵌套表达式,可以在冒号之后的父格式中的任何位置出现。

旧的格式化风格也支持某些参数化,但受到更多的限制。即它仅允许对输出的宽度和精度进行参数化。

参数化的对齐方式和宽度:

此操作不适用于旧的格式化风格。

New'{:{align}{width}}'.format('test', align='^', width='10')
Output   test   

参数化的精度:

Old'%.*s = %.*f' % (3, 'Gibberish', 3, 2.7182)
New'{:.{prec}} = {:.{prec}f}'.format('Gibberish', 2.7182, prec=3)
OutputGib = 2.718

宽度和精度:

Old'%*.*f' % (5, 2, 2.7182)
New'{:{width}.{prec}f}'.format(2.7182, width=5, prec=2)
Output 2.72

嵌套格式可用于替换格式中的任何部分,因此上述精度示例可以重写为:

此操作不适用于旧的格式化风格。

New'{:{prec}} = {:{prec}}'.format('Gibberish', 2.7182, prec='.3')
OutputGib = 2.72

日期和时间可以分别设置:

此操作不适用于旧的格式化风格。

from datetime import datetime
dt = datetime(2001, 2, 3, 4, 5)
New'{:{dfmt} {tfmt}}'.format(dt, dfmt='%Y-%m-%d', tfmt='%H:%M')
Output2001-02-03 04:05

嵌套格式可以是位置参数。位置取决于花括号的顺序:

此操作不适用于旧的格式化风格。

New'{:{}{}{}.{}}'.format(2.7182818284, '>', '+', 10, 3)
Output     +2.72

当然,可以像之前那样混合使用关键字参数:

此操作不适用于旧的格式化风格。

New'{:{}{sign}{}.{}}'.format(2.7182818284, '>', 10, 3, sign='+')
output     +2.72

自定义对象

datetime 示例通过使用 __format__() 这个神奇的方法来工作。你可以在自己的对象中通过重写此方法以定义自己的格式处理方式。这使你可以完全控制所使用的格式语法。

此操作不适用于旧的格式化风格。

class HAL9000(object):

    def __format__(self, format):
        if (format == 'open-the-pod-bay-doors'):
            return "I'm afraid I can't do that."
        return 'HAL 9000'
New'{:open-the-pod-bay-doors}'.format(HAL9000())
OutputI’m afraid I can’t do that.

本文翻译自:PyFormat: Using % and .format() for great good!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值