Python字串的格式化,看這一篇就夠了

上海小小胖發表於2019-03-25

知識星球

相信很多人在格式化字串的時候都用"%s" % v的語法,PEP 3101 提出一種更先進的格式化方法 str.format() 併成為 Python 3 的標準用來替換舊的 %s 格式化語法,CPython 從 2.6 開始已經實現了這一方法(其它直譯器未考證)。

format()

新的 format() 方法其實更像是一個簡略版的模板引起(Template Engine),功能非常豐富。

模板中替換變數用 {} 包圍,且由 : 分為兩部分,其中後半部分 format_spec 在後面會單獨討論。

前半部分有三種用法:

  • 代表位置的數字
  • 代表keyword的識別符號

這與函式呼叫的引數類別是一致的

print("{} {}".format("Hello", "World"))
# 等同於以下幾種
print("{0} {1}".format("Hello", "World"))
print("{hello} {world}".format(hello="Hello", world="World"))
print("{0}{1}{0}".format("H", "e"))

# Hello World
# Hello World
# Hello World
# HeH
複製程式碼

除此之外,就像函式引數的解包一樣,format() 中也可以直接使用解包操作

print("{author}.{city}".format(**{"author": "Miracle", "city": "上海"}))
print("{} {}".format(*["Miracle", "上海"]))

Miracle.上海
Miracle 上海
複製程式碼

在模板中還可以通過 .identifier 和 [key] 的方式獲取變數內的屬性或值(需要注意的是 "{}{}" 相當於 "{0}{1}")

data = {'author': 'Miracle', 'like': 'papapa'}
print("Author: {0[author]}, Like: {0[like]}".format(data))
langs = ["Python", "Ruby"]
print("{0[0]} vs {0[1]}".format(langs))

print("\n====\nHelp(format):{.__doc__}".format(str.format))

# Name: Python, Score: 100
# Python vs Ruby

# ====
# Help(format):
#  S.format(*args, **kwargs) -> str
複製程式碼

強制轉換,可以通過 ! + r|s|a 的方式對替換的變數進行強制轉換

  • "{!r}" 對變數呼叫 repr()
  • "{!s}" 對變數呼叫 str()
  • "{!a}" 對變數呼叫 ascii()

冒號之後的部分定義輸出的樣式

align 代表對齊方向,通常要配合 width 使用,而 fill 則是填充的字元(預設為空白):

for align, text in zip("<^>", ["left", "center", "right"]):
   # 務必看懂這句話
   print("{:{fill}{align}16}".format(text, fill=align, align=align))

print("{:0=10}".format(100)) # = 只允許數字

# left<<<<<<<<<<<<
# ^^^^^center^^^^^
# >>>>>>>>>>>right
# 0000000100
複製程式碼

同時可以看出,樣式設定裡面可以巢狀 {} ,但是必須通過 keyword 指定,且只能巢狀一層。

接下來是符號樣式:+|-|' ' 分別指定數字是否需要強制符號(其中空格是指在正數的時候不顯示 + 但保留一位空格)

print("{0:+}\n{1:-}\n{0: }".format(3.14, -3.14))

# +3.14
# -3.14
# 3.14
複製程式碼

用於表示特殊格式的數字(二進位制、十六進位制等)是否需要字首符號

逗號也是用於表示數字時是否需要在千位處進行分隔

0 相當於前面的{:0=} 右對齊並用 0 補充空位

print("Binary: {0:b} => {0:#b}".format(3))
print("Large Number: {0:} => {0:,}".format(1.25e6))
print("Padding: {0:16} => {0:016}".format(3))

# Binary: 11 => 0b11
# Large Number: 1250000.0 => 1,250,000.0
# Padding:                3 => 0000000000000003
複製程式碼

最後小胖給大家介紹一下熟悉的小數點精度問題, .n 和格式化型別。

這裡僅給出一些示例,詳細內容可以查閱文件:

from math import pi
print("pi = {pi:.2}, also = {pi:.7}".format(pi=pi))

# pi = 3.1, also = 3.141593
複製程式碼

Integer

for t in "b c d #o #x #X n".split():
   print("Type {0:>2} of {1} shows: {1:{t}}".format(t, 97, t=t))

# Type  b of 97 shows: 1100001
# Type  c of 97 shows: a
# Type  d of 97 shows: 97
# Type #o of 97 shows: 0o141
# Type #x of 97 shows: 0x61
# Type #X of 97 shows: 0X61
# Type  n of 97 shows: 97
複製程式碼

Float

for t, n in zip("eEfFgGn%", [12345, 12345, 1.3, 1.3, 1, 2, 3.14, 0.985]):
   print("Type {} shows: {:.2{t}}".format(t, n, t=t))

# Type e shows: 1.23e+04
# Type E shows: 1.23E+04
# Type f shows: 1.30
# Type F shows: 1.30
# Type g shows: 1
# Type G shows: 2
# Type n shows: 3.1
# Type % shows: 98.50%
複製程式碼

String (default)

try:
   print("{:s}".format(123))
except:
   print("{}".format(456))

# 456
複製程式碼

關注公眾號「Python專欄」,後臺回覆「騰訊架構資源1」,獲取由騰訊架構師整理的大資料學習全套資源包!

Python專欄二維碼

相關文章