格式化字符串


模板

格式化字符串時,Python使用一個字符串作為模板。模板中有格式符,這些格式符為真實值預留位置,並說明真實數值應該呈現的格式。Python用一個tuple(其實可以不寫tuple括號也可以)將多個值傳遞給模板,每個值對應一個格式符。如下面的例子:

print("I'm %s. I'm %d year old" % ('Hom', 30))

"I'm %s. I'm %d year old" 為我們的模板。%s為第一個格式符,表示一個字符串。%d為第二個格式符,表示一個整數。('Hom', 30)的兩個元素'Hom'和30為替換%s和%d的真實值。 在模板和tuple之間,有一個%號分隔,它代表了格式化操作。

整個表達式實際上構成一個字符串表達式。我們可以像一個正常的字符串那樣,將它賦值給某個變量,如:

a = "I'm %s. I'm %d year old" % ('Hom', 30)
print a

也可以用詞典來傳遞真實值,如:

print("I'm %(name)s. I'm %(age)d year old" % {'name':'Hom', 'age':30})

可以看到,我們對兩個格式符進行了命名。命名使用()括起來。每個命名對應詞典的一個key。

格式符

格式符為真實值預留位置,並控制顯示的格式。格式符可以包含有一個類型碼,用以控制顯示的類型,如下:

  • %s 字符串 (采用str()的顯示)
  • %r 字符串 (采用repr()的顯示)
  • %c 單個字符(chr()函數轉換)
  • %b 二進制整數(只能用於字符串format方法和format函數,%不能用.)
  • %d%i 十進制整數(帶符號)
  • %u 十進制整數(不帶符號)
  • %o 八進制整數
  • %x%X 十六進制整數, 區別在於輸出時大小寫.
  • %e%E 指數 (基底寫為e或E)
  • %f%F 浮點數
  • %g%G 指數(e/E)或浮點數 (根據顯示長度), 即%e%f自動判斷
  • %% 輸出字符%

要是想輸出%則要使用%%進行轉義操作.

更復雜的控制

%[(name)][flags][width].[precision]typecode

  • (name): 命名,用於字典控制賦值
  • flags: 可以有+,-,0# :
    • + 表示右對齊(默認形式)。一般在數值數據要顯示正負號時使用.
    • - 表示左對齊。
    • 為一個空格,表示在正數的左側填充一個空格,從而與負數對齊。
    • 0 表示使用0填充左側多余空格部分。僅對數值起效, 不能和-一起用.
    • # 對於八進制和十六進制, 前面顯示00x0X
  • width: 顯示寬度,總長度,會補齊空格. 該部分可以設為*, 此時長度由后面的元組中指定.
  • .precision: 對於數值, 表示小數點后精度; 對於數值轉字符串, 表示字符串有效長度(包括.+-符號). 該部分可以設為*, 此時長度由后面的元組中指定.

比如:

>>> "%s" % 1.23
'1.23'
>>> "%f" % 1.23
'1.230000'
>>> "%d" % 1.23
'1'
>>> "%e" % 1.23
'1.230000e+00'
>>> "%E" % 1.23
'1.230000E+00'

>>> "%7.3f" % 1.23
'  1.230'
>>> "%-7.3f" % 1.23
'1.230  '
>>> "%- 7.3f" % 1.23
' 1.230 '
>>> "%+7.3f" % 1.23
' +1.230'
>>> "%+08.3f" % 1.23
'+001.230'
>>> "%+7.3s" % 1.23
'    1.2'
>>> "%+7.4s" % 1.23
'   1.23'
>>> "%*.*f" % (10,4,1.23)
'    1.2300'

>>> "%d to hex is %#x" %(100, 100)
'100 to hex is 0x64'
>>> "%- *d to hex is %#X" % (7, 100, 100)
' 100    to hex is 0X64'
>>> "%(name)s is %(age)d years old" % {'name': "Zhao",'age':18}
'Zhao is 18 years old'

上面的width, precision為兩個整數。我們可以利用*,來動態代入這兩個量。比如:

print("%.*f" % (4, 1.2))  # "1.2000"

Python實際上用4來替換*。所以實際的模板為"%.4f"。

format函數和字符串format方法

這是另一種處理方法格式化方法: 通過format函數/str的format方法. 例如下面的例子:

要將一個列表(float型)的內容格式化並空格分隔寫到文件中,一行怎么寫?

 

# 利用map構造函數
f.write( ' '.join(map((lambda v: format(v, '<8.5f')),list))

# 利用列表生成器
f.write(' '.join([ "%-8.5f" % i for i in lll]))

兩者結果是一致的. 用lambda函數的好處是, 可以定義一個新函數來方便統一處理一系列的格式, 當需要修改時只修改一處即可. 而%方法則要把每處的格式化式改寫一遍.

另外, 試試:

print "%-"+str(var)+".5f" % i, 你會發現報錯: not all arguments converted during string formatting, 原因是該格式化字符串先執行再相加, 即".5f" % i優先, 要是print ("%-"+str(var)+".5f") % i 則沒有問題. 格式化串分析在字符串合並前進行,因此錯了. 但format(i, "<"+str(var)+".5f") 是可行的

format函數

format函數執行簡單的值轉換. 他不適用模板, 只是簡單地把值轉為指定的輸出格式.

format(value[, format_spec]), 后面是格式表達式的字符串, 默認是"", 即不格式化直接字符串化. 很基礎簡單的函數.

%格式化式類似, 支持上面提及的[flags][width].[precision]typecode 格式化表達式. 但注意:

  1. format函數不需要%或后面提到的:. 即直接轉換.
  2. format函數左中右對齊分別使用<^>, 而不使用-
  3. 空白部分用0填充, "0<6.3f"這些表達是一樣的. (%方法不能右側補0)
  4. 第一個特殊字符為填充的字符,只能是一個字符,不指定的話默認是用空格填充(0只是特例)
  5. 只能對單一個元素進行操作, 不支持別名(name),不支持字典, 列表等.
  6. 對於長數值, 還可以用控制符,(千位分隔符)來控制輸出成1,234,567
  7. typecode可以支持b二進制.
>>> format(3.14,'+8.4f')
' +3.1400'
>>> format(3.14,'<8.4f')
'3.1400  '
>>> format(3.14,'^8.4f')
' 3.1400 '
>>> format(3.14,'08.4f')
'003.1400'
>>> format(3.14,'0<8.4f')
'3.140000'
>>> '%0-8.4f'%3.14
'3.1400  '

>>> format(99,'b')
'1100011'
>>> format(10000000,',')
'10,000,000'

字符串的format方法

字符串的format方法是最為強大的. 支持對該字符串(作為模板)進行格式化, 又像format函數一樣有更豐富的支持.

str.format(*args, **kwargs), 支持多種方式的格式化, 在Python2.6后引入. 和之前兩種方法不同, 主要使用{}:進行控制格式化,前者指定位置, 后者相當於%.

映射式格式化

通過大括號標記為一個"元素", 然后format里的*args**kwargs逐一對應進行填充. 支持多種方式:

  • 通過索引號或位置對應: 可以使用參數位置定應的索引號進行對應, {index}; 也可以根據位置使用匿名方式(Py2.7+才支持), {},{}. 后者大括號對數超過參數個數, 或者索引號大於參數個數, 都會報錯: IndexError: tuple index out of range
'{1},{0},{1}'.format('a',5)
## a,5,a
'{},{}'.format('a',5)
## a,5
  • 通過序列調用下標
s=['Hom',30]
'{0[0]}:{0[1]}'.format(s)
## 'Hom:30'
  • 通過命名方式()

通過顯示參數賦值, 定義一個局部變量. 可以使用該局部變量名或者該對象的屬性來填充.

'{name}:{age}'.format(age=30,name="Hom")
## 'Hom:30'

c=CC(); c.name='Hom'; c.age=30
'{p.name}:{p.age}'.format(p=c)

格式限定符

首先將格式化限定式寫在{}內, :作為格式化標識開始. 同樣支持 [flags][width].[precision]typecode 格式化表達式:

  • {}將被格式化的部分寫在這里面
  • :后面接格式化表達式
  • 左中右對齊和format函數一樣, 使用<^>, 而不是-
  • 支持二進制b和千位分隔符,.(同format函數)
  • :號后面帶填充的字符,只能是一個字符,不指定的話默認是用空格填充
'{:<8.4f}'.format(6.4)
## '6.4000  '
'{:0>8}'.format('189')
## '00000189'
'{:_>8}'.format('189')
## '_____189'


'{:b}'.format(17)
## '10001'
'{:,}'.format(1234567890)
## '1,234,567,890'

string.Template 模板對象

其實,在Python中進行字符串的格式化,除了格式化操作符,還可以使用string模塊中的字符串模板(Template)對象。下面就主要看看Template對象的substitute()方法:

from string import Template

s = Template("Hi, $name! $name is learning $language")
print s.substitute(name="Zhao", language="Python")
## Hi, Zhao! Zhao is learning Python

d = {"name": "Hom", "language": "C#"}
print s.substitute(d)
## Hi, Hom! Hom is learning C#

# 用$$表示$符號
s = Template("This book ($bname) is 99$$")
print s.substitute(bname="Learning Python")
## This book (Learning Python) is 99$

這種方法比較落后少用了.

總結

Python中內置的% 操作符可用於格式化字符串操作,控制字符串的呈現格式。Python中還有其他的格式化字符串的方式,但%操作符的使用是最方便的。

format函數提供函數化的格式化辦法, 而字符串的format方法則提供更豐富的操作方式.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM