Python 的格式化字符串(f-string)的基本用法詳解
Python 的格式化字符串(f-string,格式化字符串字面量)是 Python 3.6 引入的一種強(qiáng)大且簡(jiǎn)潔的字符串格式化工具,通過在字符串前添加 f
或 F
前綴,并使用花括號(hào) {}
嵌入變量或表達(dá)式,實(shí)現(xiàn)動(dòng)態(tài)字符串生成。本文將詳細(xì)介紹 f-string 的定義、語法、用法、格式化選項(xiàng)、版本改進(jìn)、性能、適用場(chǎng)景、注意事項(xiàng)及最佳實(shí)踐。
1. 什么是 f-string?
f-string 是 Python 3.6 及以上版本支持的字符串格式化方法,由 PEP 498 – Literal String Interpolation 提出,旨在提供比傳統(tǒng) %
格式化、str.format()
和 string.Template
更簡(jiǎn)潔、可讀且高效的方式。f-string 允許在字符串字面量中直接嵌入 Python 表達(dá)式,運(yùn)行時(shí)動(dòng)態(tài)求值。
核心特點(diǎn):
- 簡(jiǎn)潔語法:通過
f"文本 {表達(dá)式}"
嵌入變量或表達(dá)式。 - 高效性能:編譯時(shí)解析為字節(jié)碼,執(zhí)行速度快。
- 靈活性:支持任意 Python 表達(dá)式,包括運(yùn)算 復(fù)雜運(yùn)算、函數(shù)調(diào)用和推導(dǎo)式。
- 格式化選項(xiàng):支持對(duì)齊、精度、類型等格式控制。
- 調(diào)試支持:Python 3.8+ 提供
=
修飾符,便于調(diào)試。
示例:
name = "Alice" age = 25 print(f"姓名: {name}, 年齡: {age}") # 輸出: 姓名: Alice, 年齡: 25
與元類的關(guān)系:雖然 f-string 本身不直接涉及元類,但其實(shí)現(xiàn)依賴 Python 的動(dòng)態(tài)求值機(jī)制,表達(dá)式在運(yùn)行時(shí)通過 eval()
解析,類似于元類在類創(chuàng)建時(shí)的動(dòng)態(tài)干預(yù)。
2. f-string 的基本語法和用法
f-string 的語法為在字符串前添加 f
或 F
,在字符串中使用 {表達(dá)式}
嵌入內(nèi)容,表達(dá)式在運(yùn)行時(shí)求值。
2.1 基本用法
f-string 支持嵌入變量、常量、算術(shù)運(yùn)算、函數(shù)調(diào)用等。
示例:
x = 10 y = 20 print(f"結(jié)果: {x + y}") # 輸出: 結(jié)果: 30 print(f"平方: {x ** 2}") # 輸出: 平方: 100 def greet(name): return f"你好, {name}!" print(greet("Bob")) # 輸出: 你好, Bob!
2.2 復(fù)雜表達(dá)式
f-string 支持列表推導(dǎo)式、字典操作等復(fù)雜表達(dá)式。
示例:
names = ["Alice", "Bob", "Charlie"] print(f"名字: {', '.join(name.upper() for name in names)}") # 輸出: 名字: ALICE, BOB, CHARLIE data = {"a": 1, "b": 2} print(f"鍵值對(duì): {list(data.items())}") # 輸出: 鍵值對(duì): [('a', 1), ('b', 2)]
2.3 多行 f-string
f-string 支持多行字符串,適合復(fù)雜格式化。
示例:
name = "Alice" age = 25 print(f""" 個(gè)人信息: 姓名: {name} 年齡: {age} """) # 輸出: # 個(gè)人信息: # 姓名: Alice # 年齡: 25
3. 格式化選項(xiàng)
f-string 使用格式說明符(format specification mini-language)控制輸出格式,語法為 {表達(dá)式:格式說明符}
,格式說明符位于 :
之后。格式說明符支持填充、對(duì)齊、寬度、精度和類型等,基于 Python 官方文檔:Common String Operations。
3.1 格式說明符語法
格式說明符 ::= [[填充]對(duì)齊][符號(hào)]["z"]["#"]["0"][寬度][分組]["." 精度][類型]
- 填充:任意字符,用于填充空白(如
_
、*
)。 - 對(duì)齊:
<
(左對(duì)齊)、>
(右對(duì)齊)、^
(居中)。 - 符號(hào):
+
(顯示正負(fù)號(hào))、-
(僅負(fù)號(hào))、空格(正數(shù)前加空格)。 - z:將負(fù)零轉(zhuǎn)為正零(Python 3.11+)。
- #:備用格式(如為十六進(jìn)制加
0x
前綴)。 - 0:數(shù)字左填充零。
- 寬度:輸出最小寬度。
- 分組:千位分隔符(
,
或_
)。 - 精度:小數(shù)點(diǎn)后位數(shù)或字符串最大長(zhǎng)度。
- 類型:如
s
(字符串)、d
(十進(jìn)制)、f
(浮點(diǎn)數(shù))、x
(十六進(jìn)制)。
3.2 常見格式化示例
對(duì)齊和填充:
name = "Bob" print(f"{name:>10}") # 輸出: " Bob"(右對(duì)齊,寬度10) print(f"{name:_<10}") # 輸出: "Bob_______"(左對(duì)齊,用_填充) print(f"{name:*^10}") # 輸出: "***Bob****"(居中,用*填充)
數(shù)字格式化:
pi = 3.14159 print(f"Pi: {pi:.2f}") # 輸出: Pi: 3.14(2位小數(shù)) print(f"Pi: {pi:,.2f}") # 輸出: Pi: 3,141.59(千位分隔) num = 42 print(f"Number: {num:05d}") # 輸出: Number: 00042(零填充) print(f"Hex: {num:#x}") # 輸出: Hex: 0x2a(十六進(jìn)制帶前綴)
其他類型:
from datetime import datetime now = datetime.now() print(f"日期: {now:%Y-%m-%d}") # 輸出: 日期: 2025-05-18
表 1:常見格式說明符
表達(dá)式 | 輸出 | 說明 |
---|---|---|
f"{pi:.2f}" | 3.14 | 浮點(diǎn)數(shù),2位小數(shù) |
f"{num:>10d}" | " 42" | 右對(duì)齊,寬度10 |
f"{pi:,.2f}" | 3,141.59 | 千位分隔,2位小數(shù) |
f"{num:+d}" | +42 | 帶符號(hào)的十進(jìn)制 |
f"{num:05d}" | 00042 | 零填充,寬度5 |
f"{num:#x}" | 0x2a | 十六進(jìn)制,帶前綴 |
4. 修飾符與調(diào)試
f-string 支持修飾符 !s
、!r
和 !a
,分別調(diào)用 str()
、repr()
和 ascii()
,用于控制表達(dá)式輸出形式。
示例:
class Person: def __init__(self, name): self.name = name def __str__(self): return f"Person: {self.name}" def __repr__(self): return f"Person(name='{self.name}')" p = Person("Charlie") print(f"{p!s}") # 輸出: Person: Charlie print(f"{p!r}") # 輸出: Person(name='Charlie') print(f"{p!a}") # 輸出: Person(name='Charlie')(ASCII 編碼)
調(diào)試模式(Python 3.8+):
使用 =
修飾符顯示表達(dá)式及其值,便于調(diào)試。
示例:
x = 10 y = 20 print(f"{x=}, {y=}, {x + y=}") # 輸出: x=10, y=20, x + y=30
5. Python 3.12 的改進(jìn)
根據(jù) What’s New In Python 3.12 和 PEP 701,Python 3.12 放寬了 f-string 的語法限制,提升靈活性:
- 支持反斜杠:允許在表達(dá)式中使用反斜杠(如
\n
)。 - 重復(fù)引號(hào):允許嵌套與 f-string 相同的引號(hào)。
- 注釋和多行表達(dá)式:支持在表達(dá)式中添加注釋和多行代碼。
示例:
words = ["hello", "world"] print(f"{'\\n'.join(words)}") # 輸出: hello\nworld # 嵌套引號(hào) print(f"{'\"quoted\"'}") # 輸出: "quoted" # 多行表達(dá)式 print(f""" 結(jié)果: { # 計(jì)算總和 sum([1, 2, 3]) } """) # 輸出: 結(jié)果: 6
這些改進(jìn)使 f-string 在復(fù)雜場(chǎng)景下更易用,研究顯示其在多行格式化和動(dòng)態(tài)生成中效果顯著。
6. 性能比較
f-string 在性能上優(yōu)于傳統(tǒng)格式化方法,因其在編譯時(shí)解析為字節(jié)碼,減少運(yùn)行時(shí)開銷。根據(jù) Real Python 的基準(zhǔn)測(cè)試(Real Python: Python’s F-String),在 1,000,000 次迭代中:
- f-string:87.08 ms
- % 運(yùn)算符:90.98 ms
- str.format():144.69 ms
原因:
- f-string 直接嵌入表達(dá)式,避免了
str.format()
的參數(shù)解析。 - 編譯時(shí)優(yōu)化,表達(dá)式求值更高效。
示例性能測(cè)試:
import timeit print(timeit.timeit('f"Number: {42}"', number=1000000)) # 更快 print(timeit.timeit('"Number: %d" % 42', number=1000000)) # 稍慢 print(timeit.timeit('"Number: {}".format(42)', number=1000000)) # 最慢
7. 適用場(chǎng)景
f-string 適用于大多數(shù)字符串格式化場(chǎng)景,包括:
- 用戶輸出:生成格式化的用戶界面文本。
score = 95 print(f"你的得分是: {score}/100") # 輸出: 你的得分是: 95/100
- 日志消息:快速構(gòu)造日志字符串(但見注意事項(xiàng))。
user = "Alice" print(f"用戶 {user} 已登錄")
- 數(shù)據(jù)格式化:處理數(shù)字、日期等。
from datetime import datetime now = datetime.now() print(f"當(dāng)前時(shí)間: {now:%Y-%m-%d %H:%M:%S}") # 輸出: 當(dāng)前時(shí)間: 2025-05-18 09:49:00
- 調(diào)試:使用
=
修飾符檢查變量值。x = 42 print(f"{x=}") # 輸出: x=42
8. 注意事項(xiàng)
盡管 f-string 功能強(qiáng)大,但需注意以下事項(xiàng):
版本兼容性:
- f-string 僅在 Python 3.6+ 可用,舊版本會(huì)拋出
SyntaxError
。 - 某些功能(如
=
修飾符)需 3.8+,反斜杠支持需 3.12+。
- f-string 僅在 Python 3.6+ 可用,舊版本會(huì)拋出
日志記錄:
- f-string 立即求值,可能在日志未記錄時(shí)浪費(fèi)資源。
- 推薦:使用
logging
模塊的%
格式化,延遲求值。import logging logging.warning("用戶 %s 已登錄", "Alice") # 優(yōu)于 f-string
安全性:
- 避免將用戶輸入直接嵌入表達(dá)式,可能導(dǎo)致代碼注入。
user_input = ".__class__.__bases__[0].__subclasses__()" # 危險(xiǎn): print(f"{eval(user_input)}")
- 對(duì)于 SQL 查詢,使用參數(shù)化查詢而非 f-string:
cursor.execute("SELECT * FROM users WHERE name = ?", (name,))
- 避免將用戶輸入直接嵌入表達(dá)式,可能導(dǎo)致代碼注入。
可讀性:
- 復(fù)雜表達(dá)式可能降低可讀性,建議拆分為多行或預(yù)計(jì)算。
# 不可讀 print(f"結(jié)果: {sum([x * y for x in range(10) for y in range(10)])}") # 改進(jìn) total = sum(x * y for x in range(10) for y in range(10)) print(f"結(jié)果: {total}")
- 復(fù)雜表達(dá)式可能降低可讀性,建議拆分為多行或預(yù)計(jì)算。
國(guó)際化:
- f-string 不直接支持動(dòng)態(tài)格式化,國(guó)際化場(chǎng)景可能需
str.format()
或模板。template = "姓名: {name}, 年齡: {age}" print(template.format(name="Alice", age=25))
- f-string 不直接支持動(dòng)態(tài)格式化,國(guó)際化場(chǎng)景可能需
9. 最佳實(shí)踐
保持簡(jiǎn)潔:
- 使用簡(jiǎn)單表達(dá)式,避免嵌套復(fù)雜邏輯。
- 示例:
# 推薦 result = x + y print(f"結(jié)果: {result}") # 避免 print(f"結(jié)果: {x + y + complex_calculation()}")
使用格式化選項(xiàng):
- 充分利用對(duì)齊、精度等功能,提升輸出美觀性。
print(f"{'項(xiàng)目':<10} {'得分':>5}") print(f"{'數(shù)學(xué)':<10} {95:>5}") # 輸出: # 項(xiàng)目 得分 # 數(shù)學(xué) 95
- 充分利用對(duì)齊、精度等功能,提升輸出美觀性。
調(diào)試優(yōu)先:
- 使用
=
修飾符快速檢查變量值。print(f"{data['key']=}") # 檢查字典值
- 使用
性能優(yōu)化:
- 在循環(huán)中優(yōu)先使用 f-string,減少格式化開銷。
for i in range(1000): print(f"迭代: {i}") # 優(yōu)于 str.format()
- 在循環(huán)中優(yōu)先使用 f-string,減少格式化開銷。
安全性檢查:
- 對(duì)用戶輸入進(jìn)行清洗,必要時(shí)使用參數(shù)化或模板。
name = sanitize_input(user_input) print(f"歡迎, {name}")
- 對(duì)用戶輸入進(jìn)行清洗,必要時(shí)使用參數(shù)化或模板。
10. 總結(jié)表
功能 | 示例 | 說明 |
---|---|---|
基本嵌入 | f"姓名: {name}" | 嵌入變量或簡(jiǎn)單表達(dá)式 |
復(fù)雜表達(dá)式 | f"{', '.join(names)}" | 支持推導(dǎo)式、函數(shù)調(diào)用 |
格式化對(duì)齊 | f"{name:>10}" | 控制寬度、填充、左右居中 |
數(shù)字格式化 | f"{pi:.2f}" | 控制精度、千位分隔、符號(hào) |
修飾符 | f"{obj!r}" | 調(diào)用 str()、repr()、ascii() |
調(diào)試模式 | f"{x=}" | 顯示表達(dá)式和值(3.8+) |
多行和注釋 | f"結(jié)果: {sum([1, 2]) # 注釋}" | 支持反斜杠、注釋(3.12+) |
11. 學(xué)習(xí)資源
- 官方文檔:
- 教程:
- 規(guī)范:
- 書籍:
- 《Fluent Python》:深入講解字符串處理。
- 《Python Cookbook》:f-string 實(shí)用案例。
12. 總結(jié)
f-string 是 Python 中最現(xiàn)代、最推薦的字符串格式化工具,憑借簡(jiǎn)潔的語法、高效的性能和豐富的格式化選項(xiàng),廣泛應(yīng)用于文本輸出、數(shù)據(jù)格式化、調(diào)試等領(lǐng)域。Python 3.8 和 3.12 的改進(jìn)進(jìn)一步增強(qiáng)了其功能,但需注意日志記錄、安全性和版本兼容性。學(xué)習(xí)者應(yīng)通過實(shí)踐掌握 f-string 的核心用法和最佳實(shí)踐,結(jié)合格式化選項(xiàng)提升代碼質(zhì)量。
到此這篇關(guān)于Python 的格式化字符串(f-string)的文章就介紹到這了,更多相關(guān)python格式化字符串內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python腳本實(shí)現(xiàn)抓取指定網(wǎng)站上的所有圖片
對(duì)于開發(fā)者、數(shù)據(jù)分析師以及研究人員而言,從網(wǎng)頁(yè)中提取有價(jià)值的信息是一項(xiàng)至關(guān)重要的技能,本文將詳細(xì)介紹如何使用Python編寫一個(gè)腳本來自動(dòng)抓取指定網(wǎng)站上的所有圖片,需要的可以參考下2024-10-10python jenkins 打包構(gòu)建代碼的示例代碼
這篇文章主要介紹了python jenkins 打包構(gòu)建代碼的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11舉例詳解Python中threading模塊的幾個(gè)常用方法
這篇文章主要介紹了舉例詳解Python中threading模塊的幾個(gè)常用方法,threading模塊用來創(chuàng)建和操作線程,是Python學(xué)習(xí)當(dāng)中的重要知識(shí),需要的朋友可以參考下2015-06-06Python實(shí)現(xiàn)接口自動(dòng)化封裝導(dǎo)出excel和讀寫excel數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了Python如何實(shí)現(xiàn)接口自動(dòng)化封裝導(dǎo)出excel和讀寫excel數(shù)據(jù),文中的示例代碼簡(jiǎn)潔易懂,希望對(duì)大家有所幫助2023-07-07Python實(shí)現(xiàn)圖片和視頻的相互轉(zhuǎn)換
有時(shí)候我們需要把很多的圖片合成視頻,或者說自己寫一個(gè)腳本去加快或者放慢視頻;也有時(shí)候需要把視頻裁剪成圖片,進(jìn)行后續(xù)操作。這篇文章就將為大家介紹如何通過Python實(shí)現(xiàn)圖片和視頻的相互轉(zhuǎn)換,需要的可以參考一下2021-12-12對(duì)pytorch網(wǎng)絡(luò)層結(jié)構(gòu)的數(shù)組化詳解
今天小編就為大家分享一篇對(duì)pytorch網(wǎng)絡(luò)層結(jié)構(gòu)的數(shù)組化詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12tensorflow 使用flags定義命令行參數(shù)的方法
本篇文章主要介紹了tensorflow 使用flags定義命令行參數(shù)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04