2.6.3 格式化输出

很多应用都要求将数据按整齐的格式输出,用 print 语句能够安排简单的格式。例如, 下面的程序画出一棵简单的圣诞树:

【程序 2.4】eg2_4.py

print "    *    " 
print "   **@   " 
print "  *@***  " 
print " *****@* " 
print "*********" 
print "    *    "
print "    *    "

可见,数据的输出位置、间隔空白等都是用最直接的手动方式安排的。执行结果如图 2.3 所 示。

① Python 3.x 与 Python 2.x 的一个重要区别是将 print 实现为一个函数,即 print(<表达式>)。

图 2.3 程序 2.4 的执行结果

如果需要设计复杂的输出格式,仅靠 print 就无能为力了,事实上 Python 提供了更好 的做法——字符串格式化运算。先看个简单例子:在财会、银行应用中,输出金额数据时有 习惯的固定格式,如一元伍角不应显示成 1.5,而应显示成¥1.50。而用普通的 print 语 句无法保留末尾的 0:

>>> print 1.50
1.5

为了解决这个问题,我们可以采用 Python 的格式化输出的功能:

>>> x = 1.5
>>> print "The amount is ¥%0.2f" % (x)
The amount is ¥1.50

这里用到了 Python 的字符串格式化运算符%。

字符串格式化运算%的一般用法如下:

<模板字符串> % (<数据 1>, ..., <数据 n>)

这个运算的结果是一个字符串,该字符串是按照模板字符串的样子构造的。模板字符串中一 般会留有一些“空位”,需要用实际数据填入这些空位。显然,空位的个数和实际数据的个 数必须对应一致。总之,向模板字符串的空位中填入了实际数据后,所得字符串就是格式化 运算的结果。

每个“空位”实际上是一个格式定义符,用于描述对填入数据的格式化处理。如上面的 例子中,模板字符串"The amount is ¥%0.2f"包含一个空位,即格式定义符%0.2f。 数据 x 的值将按照所定义的格式填充到这个空位中。具体是怎样的格式呢?

格式定义符的一般形式是:

%<宽度>.<精度><类型字符>

模板字符串中出现的格式定义符以%开头,表示一个空位,注意不要与模板字符串后面的格式化运算符%混淆。格式定义符以类型字符结尾,表示向该空位填入的数据将格式化为特定数据类型,常用的类型字符有十进制整数 d、浮点数 f、字符串 s 等。

格式定义符的中间部分包括宽度、小数点和精度,其中宽度表示“空位”的预留空间宽度(以字符计),精度用于浮点数格式,表示小数点后保留几位数字。如果实际数据的宽度 超出空位的预留宽度,则空位自动扩张至所需宽度;如果实际数据的宽度小于预留宽度,则 按预留宽度输出(这时会多出一些空白)。若省略宽度或指定宽度为 0,则表示根据实际数 据的宽度分配空间。

汇总以上说明,即可明白格式定义符%0.2f 的意思是:数据按浮点数类型格式化,根 据数据的实际宽度分配空间,保留两位小数。

另外补充两点:第一,当预留宽度大于数据的实际宽度时,该数据在预留空间内默认是 右对齐的,但可以通过在宽度前加上负号改成左对齐,如%-8.2f。第二,浮点数输出时默 认的精度是保留 6 位小数,实际数据的小数部分不足 6 位时自动补 0,超出 6 位时自动进行 舍入;如果指定过高的精度,可能导致无法精确表示。

建议读者试用各种格式定义符,以便熟练掌握格式化输出的功能。下面是一些例子:

>>> "Formatted as an int: %d" % (3.14159265)
'Formatted as an int: 3'
>>> "Formatted as a float: %f" % (3.14159265)
'Formatted as a float: 3.141593'
>>> "Formatted as a float: %.4f" % (3.14159265)
'Formatted as a float: 3.1416'
>>> "Formatted as a float %.20f" % (3.14159265)
'Formatted as a float 3.14159265000000020862'
>>> "Formatted as a string: %s" % (3.14159265)
'Formatted as a string: 3.14159265'
>>> "Formatted as a string: %20s" % (3.14159265)
'Formatted as a string: 3.14159265'
>>> "Formatted as a string: %-20s" % (3.14159265)
'Formatted as a string: 3.14159265 '
>>> "%s has won $%d!" % ("Mr. Smith",10000)
'Mr. Smith has won $10000!'
>>> "%s gives %s $%d." % ("Tom","Tim",100)
'Tom gives Tim $100.'