Basic formatting
最常见的是按照位置进行format,平常用在参数的顺序不太可能更改,并且需要用到的format比较少情况。
按照位置进行format的缺点是:元素没有用像名称之类的具有描述性的东西来表示,所以这种 format 只适用于格式化相对较少的元素的情况。
''' format字符串 ''' # 旧样式 '%s %s' % ('one', 'two') # one two # 新样式 '{} {}'.format('one', 'two') # one two Output ''' format数字''' # 旧样式 '%d %d' % (1, 2) # 1 2 # 新样式 '{} {}'.format(1, 2) # 1 2 Output ''' 还有一种新的format格式,可以给占位符一个显式的位置索引。(在Python2.6中甚至是强制的) 这样可以在不更改参数的情况下重新排列显示顺序。不过这个format不能用于旧版本。 ''' # 新样式 '{1} {0}'.format('one', 'two') # two one
Value conversion
默认情况下,新样式的简单格式化程序是调用对象的__format__()方法。如果只想呈现str(…)或repr(…)的输出,可以使用 !s 或 !r 进行标识。
在%样式中,通常使用%s表示字符串,%r表示repr(…)转换。
class Data(object): def __str__(self): return 'str' def __repr__(self): return 'repr'
# 旧样式 '%s %r' % (Data(), Data()) # str repr # 新样式 '{0!s} {0!r}'.format(Data()) # str repr
Python 3 中存在一个使用repr(…)输出但使用ascii(…)的附加转换标志。
class Data(object): def __repr__(self): return 'räpr'
# 旧样式 '%r %a' % (Data(), Data()) # räpr rxe4pr # 新样式 '{0!r} {0!a}'.format(Data()) # räpr rxe4pr
填充和对齐字符串
默认情况下,值的格式设置为只占用表示内容所需的字符数。但是,也可以定义一个值所需填充到的一个特定的长度。
不过,新样式和旧样式格式的默认对齐方式不同。旧样式默认为右对齐,而新样式默认为左对齐。
'''右对齐''' # 旧样式 '%10s' % ('test',) # test # 新样式 '{:>10}'.format('test') # test Output '''左对齐''' # 旧样式 '%-10s' % ('test',) # test # 新样式 '{:10}'.format('test') # test
另外,新样式format比起旧样式,多了可以使用指定字符填充、居中填充等功能
# 使用指定字符填充 '{:_<10}'.format('test') # test______ # 居中填充 '{:_^10}'.format('test') # ___test___ # 当使用居中填充时,如果字符串长度导致填充字符两端长度不同,则多的字符将放置在右侧: '{:_^6}'.format('zip')# _zip__
截取长字符串
与填充相反,也可以将过长的字符串截断为特定数量的字符。
# 旧样式 '%.5s' % ('xylophone') # xylop # 新样式 '{:.5}'.format('xylophone') # xylop
截断和填充相结合
# 旧样式 '%-10.5s' % ('xylophone') # xylop # 新样式 '{:_<10.5}'.format('xylophone') # xylop_____
format数字
'''整型''' # 旧样式 '%d' % (42) # 42 # 新样式 '{:d}'.format(42) # 42 Output '''浮点型''' # 旧样式 '%f' % (3.141592653589793) # 3.141593 # 新样式 '{:f}'.format(3.141592653589793) # 3.141593
数字的填充和截断
# 旧样式 '%4d' % (42,) # 42 # 新样式 '{:4d}'.format(42) # 42 # 同样类似于截断字符串,浮点数的精度限制小数点后的位置数。 # 对于浮点,填充值表示完整输出的长度。 #在下面的示例中,我们希望输出至少有6个字符,小数点后有2个字符。 # 旧样式 '%06.2f' % (3.141592653589793,) # 003.14 # 新样式 '{:06.2f}'.format(3.141592653589793) # 003.14 Output # 对于提供精度的整数值来说,没有多大意义,实际上在新样式中是禁止的(它将导致valueerror)。 # 旧样式 '%04d' % (42,) # 0042 # 新样式 '{:04d}'.format(42) # 0042
给数字加符号
默认情况下,只有负数的前缀有符号,不过我们也可以把正数的加上。
# 旧样式 '%+d' % (42) # +42 # 新样式 '{:+d}'.format(42) # +42 '''使用空格字符表示负数应以减号作为前缀,正数应使用前导空格''' # 旧样式 '% d' % ((- 23)) # -23 '% d' % (42) # 42 # 新样式 '{: d}'.format((- 23)) # -23 '{: d}'.format(42) # 42 '''新样式格式还可以控制符号相对于填充的位置。此操作不能用于旧样式格式''' # 新样式 '{:=5d}'.format((- 23)) # - 23 '{:=+5d}'.format(23) # + 23
命名占位符
占位符支持命名,这样就可以参数的传递就可以多样化,既可以是字典的形式也可以是键值对的形式
# 传递的参数 data = {'first': 'hello', 'last': 'world!'} # 旧样式 '%(first)s %(last)s' % data # hello world! # 新样式 '{first} {last}'.format(**data) # hello world! # 新版本 '{first} {last}'.format(first='hello', last='world!') # hello world!
Getitem 和 Getattr
此操作不能用于旧样式格式。
新的样式格式允许在访问嵌套数据结构时具有更大的灵活性。它支持访问支持类似“getitem”的容器,例如字典和列表:
# 传递的参数 person = {'first': 'Jean-Luc', 'last': 'Picard'} # 新样式 '{p[first]} {p[last]}'.format(p=person) # Jean-Luc Picard # 传递的参数 data = [4, 8, 15, 16, 23, 42] # 新样式 '{d[4]} {d[5]}'.format(d=data) # 23 42 '''通过getAttr()访问对象上的属性''' class Plant(object): type = 'tree' # 新样式 '{p.type}'.format(p=Plant()) # tree '''以上两种类型可以自由混合和任意嵌套''' class Plant(object): type = 'tree' kinds = [{'name': 'oak'}, {'name': 'maple'}] # 新样式 '{p.type}: {p.kinds[0][name]}'.format(p=Plant()) # tree: oak
Datetime
此操作不能用于旧样式格式。
新样式格式还允许对象控制自己的渲染。例如,允许以内联方式格式化日期时间对象:
from datetime import datetime # 新样式 '{:%Y-%m-%d %H:%M}'.format(datetime(2001, 2, 3, 4, 5)) # 2001-02-03 04:05
参数化formats
新样式format允许使用参数化动态指定格式的所有组件。参数化格式是大括号中的嵌套表达式,可以出现在冒号后面的父格式中的任何位置。
旧样式的格式也支持一些参数化,但更为有限。也就是说,它只允许对输出的宽度和精度进行参数化。
'''对齐和长度参数化 ''' # 不支持旧样式 # 新样式 '{:{align}{width}}'.format('test', align='^', width='10') # test '''精度参数化''' # 旧样式 '%.*s = %.*f' % (3, 'Gibberish', 3, 2.7182) # Gib = 2.718 # 新样式 '{:.{prec}} = {:.{prec}f}'.format('Gibberish', 2.7182, prec=3) # Gib = 2.718 '''长度和精度参数化''' # 旧样式 '%*.*f' % (5, 2, 2.7182) # 2.72 # 新样式 '{:{width}.{prec}f}'.format(2.7182, width=5, prec=2) # 2.72 '''嵌套format可用于替换format的任何部分,因此上面的精度示例可重写为''' # 不支持旧样式 # 新样式 '{:{prec}} = {:{prec}}'.format('Gibberish', 2.7182, prec='.3') # Gib = 2.72 '''日期时间的组成部分可以单独设置''' # 不支持旧样式 from datetime import datetime dt = datetime(2001, 2, 3, 4, 5) # 新样式 '{:{dfmt} {tfmt}}'.format(dt, dfmt='%Y-%m-%d', tfmt='%H:%M') # 2001-02-03 04:05 '''嵌套formats可以是位置参数。位置取决于大括号的顺序''' # 不支持旧样式 # 新样式 '{:{}{}{}.{}}'.format(2.7182818284, '>', '+', 10, 3) # +2.72 '''关键字参数可以添加到组合中''' # 不支持旧样式 # 新样式 '{:{}{sign}{}.{}}'.format(2.7182818284, '>', 10, 3, sign='+') # +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' # 新样式 '{:open-the-pod-bay-doors}'.format(HAL9000()) # I'm afraid I can't do that.