2、格式化字符串
1.字符串格式化
python格式化字符串有三種方式:
- python所有版本都能用的 %
- 2.5版本以后添加的
format()函數 - 3.6后的f字符串
1.1 %格式化
>>> print('%s has %d quote types.' % ('Python', 2))
Python has 2 quote types.
-
'%'字符,用于標記轉換符的起始。 -
映射鍵(可選),由加圓括號的字符序列組成 (例如
(somename))。>>> 'name:%(name)s, age:%(age)s' % ({'name':'daming', 'age':'18'}) 'name:daming, age:18' #在此情況下格式中不能出現 * 標記符(因其需要一個序列類的參數列表)。 -
轉換旗標(可選),用于影響某些轉換類型的結果。
| 旗標 | 含意 |
|---|---|
'#' |
值的轉換將使用“替代形式”。 '%#x' % 17 |
'0' |
轉換將為數字值填充零字符。'%09d' % 5 |
'-' |
轉換值將靠左對齊(如果同時給出 '0' 轉換,則會覆蓋后者)。'%-9d' % 5 |
' ' |
(空格) 符號位轉換產生的正數(或空字符串)前將留出一個空格。'% d' % 5 |
'+' |
符號字符 ('+' 或 '-') 將顯示于轉換結果的開頭(會覆蓋 "空格" 旗標)。'%+d' % 5 |
-
最小字段寬度(可選)。 如果指定為
'*'(星號),則實際寬度會從 values 元組的下一元素中讀取,要轉換的對象則為最小字段寬度和可選的精度之后的元素。 -
精度(可選),以在
'.'(點號) 之后加精度值的形式給出。 如果指定為'*'(星號),則實際精度會從 values 元組的下一元素中讀取,要轉換的對象則為精度之后的元素。>>> '%*.*f %*s'%(20,6,5, 10,'a') ' 5.000000 a' -
長度修飾符(可選)。
>>> 'ss:%10s' % 6 'ss: 6' -
轉換類型。如上述的s,用與將值裝換成字符類型
格式化的類型:
| 轉換符 | 含意 | 備注 |
|---|---|---|
'd' |
有符號十進制整數。 | |
'i' |
有符號十進制整數。 | |
'o' |
有符號八進制數。 | (1) |
'u' |
過時類型 -- 等價于 'd'。 |
(6) |
'x' |
有符號十六進制數(小寫)。 | (2) |
'X' |
有符號十六進制數(大寫)。 | (2) |
'e' |
浮點指數格式(小寫)。 | (3) |
'E' |
浮點指數格式(大寫)。 | (3) |
'f' |
浮點十進制格式。 | (3) |
'F' |
浮點十進制格式。 | (3) |
'g' |
浮點格式。 如果指數小于 -4 或不小于精度則使用小寫指數格式,否則使用十進制格式。 | (4) |
'G' |
浮點格式。 如果指數小于 -4 或不小于精度則使用大寫指數格式,否則使用十進制格式。 | (4) |
'c' |
單個字符(接受整數或單個字符的字符串)。 | |
'r' |
字符串(使用 repr() 轉換任何 Python 對象)。 |
(5) |
's' |
字符串(使用 str() 轉換任何 Python 對象)。 |
(5) |
'a' |
字符串(使用 ascii() 轉換任何 Python 對象)。 |
(5) |
'%' |
不轉換參數,在結果中輸出一個 '%' 字符。 |
注釋:
-
此替代形式會在第一個數碼之前插入標示八進制數的前綴 (
'0o')。 -
此替代形式會在第一個數碼之前插入
'0x'或'0X'前綴(取決于是使用'x'還是'X'格式)。 -
此替代形式總是會在結果中包含一個小數點,即使其后并沒有數碼。
小數點后的數碼位數由精度決定,默認為 6。
-
此替代形式總是會在結果中包含一個小數點,末尾各位的零不會如其他情況下那樣被移除。
小數點前后的有效數碼位數由精度決定,默認為 6。
-
如果精度為
N,輸出將截短為N個字符。 -
參見 PEP 237。
>>> '%6.2i' % -6
' -06'
>>> '%6.2d' % -6
' -06'
>>>
>>> '%o' % 9
'11'
>>> '%#o' % 9
'0o11'
>>>
>>> '%x' % 17
'11'
>>> '%X' % 17
'11'
>>> '%#x' % 17
'0x11'
>>> '%#X' % 17
'0X11'
>>>
>>> '%.e' % 1000000000000000000000000000000000
'1e+33'
>>> '%.2e' % 1000000000000000000000000000000000
'1.00e+33'
>>> '%.E' % 1000000000000000000000000000000000
'1E+33'
>>> '%#.E' % 1000000000000000000000000000000000
'1.E+33'
>>> '%.f' % 5
'5'
>>> '%.F' % 5
'5'
>>> '%#.F' % 5
'5.'
>>> '%#.f' % 5
'5.'
>>> '%.5g' % 0.0001
'0.0001'
>>> '%.5g' % 0.000001
'1e-06'
>>> '%.5G' % 0.0001
'0.0001'
>>> '%.5G' % 0.000001
'1E-06'
>>> '%#.5G' % 0.0001
'0.00010000'
>>> '%#.5G' % 0.000001
'1.0000E-06'
>>> '%#.G' % 1
'1.'
1.2 format()函數
在大多數情況下,舊的語法和新語法可以轉換的
'%03.2f' % 5 等于'{:03.2f}'.format(5)
格式字符串包含有以花括號 {} 括起來的“替換字段”。 不在花括號之內的內容被視為字面文本,會不加修改地復制到輸出中。 如果你需要在字面文本中包含花括號字符,可以通過重復來轉義: {{ and }}。
一些簡單的格式字符串示例:
"First, thou shalt count to {0}" # 引用第一個位置參數
"Bring me a {}" # 隱式引用第一個位置參數
"From {} to {}" # 等同于 "From {0} to {1}"
"My quest is {name}" # 引用關鍵字參數 'name'
"Weight in tons {0.weight}" # 第一個位置參數的 'weight' 屬性
"Units destroyed: {players[0]}" # 關鍵字參數 'players' 的第一個元素。
目前支持的轉換旗標有三種: '!s' 會對值調用 str(),'!r' 調用 repr() 而 '!a' 則調用 ascii()。
"Harold's a clever {0!s}" # 先在參數上調用 str()
"Bring out the holy {name!r}" # 先在參數上調用 repr()
"More {!a}" # 先在參數上調用 ascii()
格式規格迷你語言
標準格式說明符 的一般形式如下:
format_spec ::= [[fill]align][sign]["z"]["#"]["0"][width][grouping_option]["." precision][type]
fill ::= <any character>
align ::= "<" | ">" | "=" | "^"
sign ::= "+" | "-" | " "
width ::= digit+
grouping_option ::= "_" | ","
precision ::= digit+
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
各種對齊選項的含義如下:
| 選項 | 含意 |
|---|---|
'<' |
強制字段在可用空間內左對齊(這是大多數對象的默認值)。 |
'>' |
強制字段在可用空間內右對齊(這是數字的默認值)。 |
'=' |
強制在符號(如果有)之后數碼之前放置填充。 這被用于以 '+000000120' 形式打印字段。 這個對齊選項僅對數字類型有效。 這是當 '0' 緊接在字段寬度之前時的默認選項。 |
'^' |
強制字段在可用空間內居中。 |
sign 選項僅對數字類型有效,可以是以下之一:
| 選項 | 含意 |
|---|---|
"+" |
表示標志應該用于正數和負數。 |
"-" |
表示標志應僅用于負數(這是默認行為)。 |
" " |
表示應在正數上使用前導空格,在負數上使用減號。 |
在 3.11 版本發生變更: ‘z’選項將負零浮點值在舍入到格式精度后強制轉換為正零。此選項僅對浮點表示類型有效。
在 3.1 版本發生變更:',' 選項表示使用逗號作為千位分隔符。 對于感應區域設置的分隔符,請改用 'n' 整數表示類型。
>>> '{:,d}'.format(1000000000)
'1,000,000,000'
在 3.6 版本發生變更: '_' 選項表示對浮點表示類型和整數表示類型 'd' 使用下劃線作為千位分隔符。 對于整數表示類型 'b', 'o', 'x' 和 'X',將為每 4 個數位插入一個下劃線。 對于其他表示類型指定此選項則將導致錯誤。
>>> '{:_d}'.format(1000000000)
'1_000_000_000'
>>> '{:_x}'.format(100000000000000)
'5af3_107a_4000'
width 是一個定義最小總字段寬度的十進制整數,包括任何前綴、分隔符和其他格式化字符。 如果未指定,則字段寬度將由內容確定。
當未顯式給出對齊方式時,在 width 字段前加一個零 ('0') 字段將為數字類型啟用感知正負號的零填充。 這相當于設置 fill 字符為 '0' 且 alignment 類型為 '='。
在 3.10 版本發生變更: 在 width 字段之前添加 '0' 不會再影響字符串的默認對齊。
precision 是一個十進制整數,表示浮點數的精度(小數點后顯示多少個數位),或者字符串的最大長度
可用的字符串表示類型:
類型 含意 's'字符串格式。這是字符串的默認類型,可以省略。 None 和 's'一樣。
>>> '{}'.format(5)
'5'
>>> '{!s}'.format(5)
'5'
>>> '{:s}'.format('a')
'a'
| 格式規格迷你語言與%對比 | |
|---|---|
| 缺少: | |
'i' |
有符號十進制整數。 |
'u' |
過時類型 -- 等價于 'd'。 |
| 新增: | |
'n' |
數字。 這與 'g' 相似,不同之處在于它會使用當前區域設置來插入適當的數字分隔字符。 |
'%' |
百分比。 將數字乘以 100 并顯示為定點 ('f') 格式,后面帶一個百分號。 |
| None | 總體效果是將 str() 的輸出匹配為其他格式化因子所調整出的樣子。 |
按位置訪問參數:
>>> '{0}, {1}, {2}'.format('a', 'b', 'c')
'a, b, c'
>>> '{}, {}, {}'.format('a', 'b', 'c') # 3.1+ only,等于示例1
'a, b, c'
>>> '{2}, {1}, {0}'.format('a', 'b', 'c')
'c, b, a'
>>> '{2}, {1}, {0}'.format(*'abc') # 解包參數序列
'c, b, a'
>>> '{0}{1}{0}'.format('abra', 'cad') # 參數的索引可重復使用
'abracadabra'
按名稱訪問參數:
>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W') #以關鍵字形式傳入
'Coordinates: 37.24N, -115.81W'
>>> coord = {'latitude': '37.24N', 'longitude': '-115.81W'}
>>> 'Coordinates: {latitude}, {longitude}'.format(**coord) #解包字典
'Coordinates: 37.24N, -115.81W'
訪問參數的屬性:
>>> c = 3-5j
>>> ('The complex number {0} is formed from the real part {0.real} '
... 'and the imaginary part {0.imag}.').format(c)
'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.'
>>> class Point:
... def __init__(self, x, y):
... self.x, self.y = x, y
... def __str__(self):
... return 'Point({self.x}, {self.y})'.format(self=self)
...
>>> str(Point(4, 2))
'Point(4, 2)'
訪問參數的項:
>>> coord = (3, 5)
>>> 'X: {0[0]}; Y: {0[1]}'.format(coord)
'X: 3; Y: 5'
替代 %s 和 %r:
>>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
"repr() shows quotes: 'test1'; str() doesn't: test2"
對齊文本以及指定寬度:
>>> '{:<30}'.format('left aligned')
'left aligned '
>>> '{:>30}'.format('right aligned')
' right aligned'
>>> '{:^30}'.format('centered')
' centered '
>>> '{:*^30}'.format('centered') # 使用 '*' 作為填充字符
'***********centered***********'
替代 %+f, %-f 和 % f 以及指定正負號:
>>> '{:+f}; {:+f}'.format(3.14, -3.14) # 總是顯示
'+3.140000; -3.140000'
>>> '{: f}; {: f}'.format(3.14, -3.14) # 對正數顯示一個空格
' 3.140000; -3.140000'
>>> '{:-f}; {:-f}'.format(3.14, -3.14) # 只顯示負號 -- 等同于 '{:f}; {:f}'
'3.140000; -3.140000'
替代 %x 和 %o 以及轉換基于不同進位制的值:
>>> # 格式也支持二進制數
>>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)
'int: 42; hex: 2a; oct: 52; bin: 101010'
>>> # with 0x, 0o, or 0b as prefix:
>>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)
'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'
使用逗號作為千位分隔符:
>>> '{:,}'.format(1234567890)
'1,234,567,890'
表示為百分數:
>>> points = 19
>>> total = 22
>>> 'Correct answers: {:.2%}'.format(points/total)
'Correct answers: 86.36%'
使用特定類型的專屬格式化:
>>> import datetime
>>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)
>>> '{:%Y-%m-%d %H:%M:%S}'.format(d)
'2010-07-04 12:15:58'
嵌套參數以及更復雜的示例:
>>> for align, text in zip('<^>', ['left', 'center', 'right']):
... '{0:{fill}{align}16}'.format(text, fill=align, align=align)
...
'left<<<<<<<<<<<<'
'^^^^^center^^^^^'
'>>>>>>>>>>>right'
>>>
>>> octets = [192, 168, 0, 1]
>>> '{:02X}{:02X}{:02X}{:02X}'.format(*octets)
'C0A80001'
>>> int(_, 16) # _ = 'C0A80001'
3232235521
>>>
>>> width = 5
>>> for num in range(5,12):
... for base in 'dXob':
... print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ')
... print()
...
5 5 5 101
6 6 6 110
7 7 7 111
8 8 10 1000
9 9 11 1001
10 A 12 1010
11 B 13 1011
1.3 f 字符串
格式字符串字面值 或稱 f-string 是標注了 'f' 或 'F' 前綴的字符串字面值。這種字符串可包含替換字段,即以 {} 標注的表達式。其他字符串字面值只是常量,格式字符串字面值則是可在運行時求值的表達式。
a = 'daming'
f"xxx{a[=]["!" ["s" | "r" | "a"]][":" format_spec}"
雙花括號 '{{' 或 '}}' 被替換為單花括號
在 3.7 版本發生變更: Python 3.7 以前, 因為實現的問題,不允許在格式字符串字面值表達式中使用 await 表達式與包含 async for 子句的推導式。
在 3.12 版本發生變更: 在 Python 3.12 之前,不允許在 f-字符串的替換字段中使用注釋。
版本新增3.8: 等號 '='。
表達式里含等號 '=' 時,輸出內容包括表達式文本、'=' 、求值結果。輸出內容可以保留表達式中左花括號 '{' 后,及 '=' 后的空格。沒有指定格式時,'=' 默認調用表達式的 repr()。指定了格式時,默認調用表達式的 str(),除非聲明了轉換字段 '!r'。
>>> a = 3 + 6
>>> f'{a = }'
'a = 9'
格式字符串字面值示例如下:
>>> name = "Fred"
>>> f"He said his name is {name!r}."
"He said his name is 'Fred'."
>>> f"He said his name is {repr(name)}." # repr() 等價于 !r
"He said his name is 'Fred'."
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # 嵌套的字段
'result: 12.35'
>>> today = datetime(year=2017, month=1, day=27)
>>> f"{today:%B %d, %Y}" # 使用日期格式說明符
'January 27, 2017'
>>> f"{today=:%B %d, %Y}" # 使用日期格式說明符和調試
'today=January 27, 2017'
>>> number = 1024
>>> f"{number:#0x}" # 使用整數格式說明符
'0x400'
>>> foo = "bar"
>>> f"{ foo = }" # 保留空格
" foo = 'bar'"
>>> line = "The mill's closed"
>>> f"{line = }"
'line = "The mill\'s closed"'
>>> f"{line = :20}"
"line = The mill's closed "
>>> f"{line = !r:20}"
'line = "The mill\'s closed" '
允許在替換字段中重用外層 f-字符串的引號類型:
>>> a = dict(x=2)
>>> f"abc {a["x"]} def"
'abc 2 def'
在 3.12 版本發生變更: 在 Python 3.12 之前不允許在替換字段中重用與外層 f-字符串相同的引號類型。
替換字段中也允許使用反斜杠并會以與在其他場景下相同的方式求值:
>>> a = ["a", "b", "c"]
>>> print(f"List a contains:\n{"\n".join(a)}")
List a contains:
a
b
c
在 3.12 版本發生變更: 在 Python 3.12 之前,f-字符串的替換字段內不允許使用反斜杠。
即便未包含表達式,格式字符串字面值也不能用作文檔字符串。
>>> def foo():
... f"Not a docstring"
...
>>> foo.__doc__ is None
True
浙公網安備 33010602011771號