目次
- 1 1. 如何在 Python 中讀取 YAML?|本文概要與目標讀者
- 2 2. YAML 是什麼?|與 JSON 的差異與特點簡單比較
- 3 3. 使用 Python 處理 YAML 的準備|PyYAML 的安裝
- 4 4. 【基本】使用 Python 讀取 YAML 檔案的方法(safe_load 的用法)
- 5 5. safe_load 和 load 的差異|Python 中 YAML 讀取的注意事項
- 6 6. 常見錯誤及其解決方法|Python YAML 讀取的陷阱
- 7 7. 應用:讀取多個文件的 YAML 文件的方法(safe_load_all)
- 8 8. 【補足】使用 YAML 作為設定檔案時的要點
- 9 9. 常見問題(FAQ)
- 10 10. 總結|掌握Python中的YAML讀取
1. 如何在 Python 中讀取 YAML?|本文概要與目標讀者
想在 Python 中處理 YAML 的您
在 Python 中開發應用程式或工具時,會越來越多情況想要使用 YAML 格式來處理「設定檔」或「外部資料的管理」。特別是 YAML 比 JSON 更具可讀性,且能以簡單的描述方式撰寫,因此在工程師或資料科學家之間,也是一種極受歡迎的資料格式。 例如,以下這些用途就需要讀取 YAML:- 將 Web 應用程式或腳本的設定檔外部化
- 想在 Python 中解析Docker Compose 或 Kubernetes的設定檔
- 想用 YAML 管理機器學習框架的參數
本文可學到的事
這篇文章將以易懂的方式,向初學者說明在 Python 中安全且確實讀取 YAML 檔案的方法。具體來說,將涵蓋以下重點:- YAML 檔案的基本結構與特點
- Python 中的讀取方法(
safe_load()的用法) - 常見錯誤及其對策
- 多重文件讀取或設定檔的實務範例
load() 與 safe_load() 的差異等,不太為人知的情資。最後,還準備了常見問題(FAQ),您的疑問一定能迎刃而解。目標讀者
這篇文章的對象為以下人士:- 想在 Python 中使用 YAML 的初學者~中級者
- 需要處理設定檔的開發者
- 對 PyYAML 的用法感到不安的人
- 想詳細了解
safe_load()或錯誤對應的人
Ad
2. YAML 是什麼?|與 JSON 的差異與特點簡單比較
YAML 是什麼?
YAML(讀作 yamu-er,或 yamuru)是「YAML Ain’t Markup Language(YAML 不是標記語言)」的遞迴縮寫,主要為了讓人類更容易讀寫結構化資料而設計的格式。與 Python 或 Ruby 等程式語言相性良好,常被用於設定檔或資料交換的場合。 YAML 使用縮排來表現階層結構,簡單且直觀的描述是其主要特點。與 JSON 的差異
YAML 與 JSON 用於類似的用途,但兩者有幾個明確的差異。以下比較代表性的項目。| 比較項目 | YAML | JSON |
|---|---|---|
| 可讀性 | 高(對人類友好) | 中等(對機器友好) |
| 註解的記述 | 可能(使用 #) | 不可 |
| 檔案大小 | 傾向較小(符號較少) | 稍大 |
| 資料結構的表現 | 自由度更高(複雜結構也 OK) | 以陣列・物件為中心 |
| 擴展性 | 高(可定義自有結構) | 有限制 |
| 支援情況 | 部分有限制 | 廣泛支援 |
YAML 的優點
使用 YAML 有以下優點:- 直觀的寫法:類似 Python 的縮排,容易掌握結構
- 可寫註解:方便在設定檔中添加補充說明
- 不冗長:不需要 JSON 般的中括弧或雙引號
- 對人類友好:非工程師也能輕鬆閱讀與修改
YAML 的使用場合
YAML 常被以下工具或系統使用:- Docker Compose(
docker-compose.yml) - Kubernetes 的設定檔(Pod 或 Service 的定義)
- CI/CD 工具(GitHub Actions、GitLab CI 等)
- 機器學習函式庫(PyTorch Lightning 或 Hydra 等)
- Web 應用程式或腳本的設定檔
3. 使用 Python 處理 YAML 的準備|PyYAML 的安裝
什麼是 PyYAML?
使用 Python 讀取或寫入 YAML 檔案時,通常會使用外部程式庫「PyYAML」。PyYAML 是一個基於 YAML 1.1 規格的簡單且功能豐富的程式庫,因為它不包含在 Python 的標準程式庫中,因此需要另外安裝。 使用 PyYAML 後,可以將 YAML 檔案作為 Python 的字典(dict)或清單(list)來處理。這樣一來,設定檔案的讀寫以及結構化資料的操作就能更直觀地進行。PyYAML 的安裝方法
PyYAML 的安裝非常簡單。如下所示,可以使用pip 在命令列(或終端機)中安裝。pip install pyyaml※如果環境中沒有 pip,則使用 python -m pip install pyyaml 也沒問題。建議使用虛擬環境
如果想分離開發環境,建議在 虛擬環境(venv 或 conda) 中安裝。處理多個專案時,程式庫的版本管理會更容易。# 虛擬環境的建立
python -m venv venv
# 啟用虛擬環境
# Windows 的情況
venv\Scripts\activate
# macOS/Linux 的情況
source venv/bin/activate
# 安裝 PyYAML
pip install pyyaml安裝確認方法
安裝後,可以在 Python 的互動模式(REPL)或腳本中如以下所述,來確認程式庫是否能正確匯入。import yaml
print(yaml.__version__)如果沒有出現錯誤,則 PyYAML 已正常安裝。確認版本有助於未來的故障排除。Ad
4. 【基本】使用 Python 讀取 YAML 檔案的方法(safe_load 的用法)
最基本的讀取方法:safe_load()
使用 PyYAML 讀取 YAML 檔案時,最常使用的函數是 safe_load()。這個函數是為了安全讀取 YAML 而設計的函數,可以將讀取的資料取得為 Python 的字典(dict)或列表(list)。 首先,讓我們看看基本的 YAML 檔案及其讀取程式碼。範例 YAML 檔案(config.yaml)
app:
name: SampleApp
version: 1.0.0
debug: true
servers:
- host: localhost
port: 8000
- host: example.com
port: 443像這樣,包含巢狀結構或列表的 YAML 檔案,是非常適合用作設定檔案的形式。Python 中的讀取程式碼範例
使用以下程式碼,可以讀取上述的 YAML 檔案:import yaml
with open('config.yaml', 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
print(config)輸出範例(Python 的字典形式)
{
'app': {'name': 'SampleApp', 'version': '1.0.0'},
'debug': True,
'servers': [
{'host': 'localhost', 'port': 8000},
{'host': 'example.com', 'port': 443}
]
}像這樣,YAML 檔案可以直接作為 Python 的原生資料結構來處理,因此可以順利用於後續的處理。open()函數中指定編碼很重要
特別是處理包含日文的 YAML 檔案時,請不要忘記在 open()函數中encoding='utf-8' 指定。如果省略,在 Windows 環境中可能會發生文字亂碼。小提示:with語法的活用
在讀取檔案時,像 with open(...) as f: 這樣使用with語法,可以防止檔案關閉遺漏,並安全地進行處理。這是 Python 的最佳實踐,推薦的寫法。5. safe_load 和 load 的差異|Python 中 YAML 讀取的注意事項
safe_load() 和 load() 有什麼不同?
PyYAML 有多個用來讀取 YAML 檔案的函數,但最容易混淆的便是 safe_load() 和 load() 的差異。 乍看之下,兩者都是用來將 YAML 讀取為 Python 資料的函數,但在安全性與功能方面有很大的差異。若使用錯誤,可能會有被外部惡意 YAML 檔案執行程式碼的危險,因此理解並正確區分使用非常重要。safe_load() 的特點(安全的讀取)
import yaml
with open('config.yaml', 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)- 應使用的基本函數
- 安全性高(不讀取任意的 Python 物件)
- 限制於基本資料型(字典、列表、字串、數值等)
- 嘗試讀取未知的型別或物件時會發生錯誤
safe_load() 如其名所示,是用來進行「安全的讀取」的函數,在處理設定檔案或外部資料時,大多數情況下使用此函數是最佳選擇。load() 的特點(靈活但有風險)
import yaml
with open('config.yaml', 'r', encoding='utf-8') as f:
data = yaml.load(f, Loader=yaml.FullLoader)- 能更靈活地解釋 YAML
- 可還原 Python 物件(例如:函數、類別實例等)
- 由於安全性風險,必須指定 Loader
load(),但現在要求明確指定 Loader。若不指定任何東西使用,會發生以下類似的警告或錯誤:yaml.YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated這是因為 load() 在過去包含了可能執行任意 Python 物件的漏洞。也就是說,若讀取不正當的 YAML 檔案,可能會無意中執行 Python 程式碼的風險。Loader 的種類(安全性和靈活性的差異)
| Loader 名稱 | 特點 | 推薦度 |
|---|---|---|
SafeLoader | 僅讀取基本型別(安全) | ◎ |
FullLoader | 允許更多 Python 型別(注意安全性) | ○ |
UnsafeLoader | 允許讀取任意物件(危險) | × |
結論:通常使用 safe_load()
如果您只是將 YAML 檔案作為設定檔案或外部資料讀取,那麼 safe_load() 就足夠了,而且應該使用它。load() 僅限於特殊用途(例如,想要反序列化自製的 Python 物件等情況)使用。Ad
6. 常見錯誤及其解決方法|Python YAML 讀取的陷阱
YAML 讀取時絆倒的原因是什麼?
YAML 是一種非常簡單且易讀的格式,但因此對細微的語法規則非常嚴格。特別是在使用 Python 讀取時,新手容易忽略的一些要點。 在本節中,我們將具體介紹使用 Python 讀取 YAML 檔案時常見的錯誤、其原因以及解決方法。1. 縮排錯誤導致的語法錯誤
在 YAML 中,縮排是顯示結構的重要元素。如果空格或 Tab 不一致,讀取時就會發生錯誤。範例:有縮排錯誤的 YAML
user:
name: Alice
age: 30錯誤訊息範例:
yaml.scanner.ScannerError: mapping values are not allowed here解決方法:
- 以2~4 個空格統一縮排(不要使用 Tab)
- 子元素要比父元素縮排更深
2. 檔案編碼導致字元亂碼
如果 YAML 檔案包含日文等非 ASCII 字元,若不適當指定編碼,就會發生字元亂碼或解碼錯誤。錯誤範例:
UnicodeDecodeError: 'cp932' codec can't decode byte...解決方法:
with open('config.yaml', 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)- 明確指定
encoding='utf-8'即可解決 - 在 Windows 環境中特別容易忘記的要點
3. 檔案路徑錯誤/不存在的檔案
雖然是簡單的錯誤,但如果指定的 YAML 檔案不存在,就會發生FileNotFoundError。錯誤範例:
FileNotFoundError: [Errno 2] No such file or directory: 'config.yaml'解決方法:
- 確認是否以絕對路徑或正確的相對路徑指定
- 檢查檔案名稱或副檔名是否有輸入錯誤
- 確認檔案是否位於與腳本相同的目錄
4. 使用 safe_load 讀取的結果為None
即使 YAML 的語法本身正確,如果檔案內容為空或僅有註解,也會發生這種現象。範例:
# 這個檔案中沒有任何設定結果:
data = yaml.safe_load(f)
print(data) # 輸出: None解決方法:
- 確認檔案中是否有記述有效的 YAML 資料
- 僅有註解或空白時,返回
None是正常的行為
5. 過於複雜的 YAML 結構解析錯誤
在大規模且巢狀深的 YAML 檔案中,由於語法錯誤或錯誤使用錨點/別名,也可能發生錯誤。解決方法:
- 逐步確認語法(以小區段為單位驗證)
- 建議捕捉
yaml.YAMLError例外並確認詳細訊息
try:
with open('config.yaml', 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)
except yaml.YAMLError as e:
print(f"YAML 讀取錯誤: {e}")總結:發生錯誤時不要慌張,檢查語法和環境
只要在撰寫時稍加注意,YAML 就是非常易於處理的格式。如果發生錯誤,請檢查以下要點:- 縮排是否正確(是否未使用 Tab)
- 檔案的編碼是否為 UTF-8
- 檔案是否存在
- YAML 的內容是否正確記述
Ad
7. 應用:讀取多個文件的 YAML 文件的方法(safe_load_all)
YAML 可以包含多個文件在單一文件中
YAML 的一個主要特點是,可以在一個文件中定義多個資料區塊(文件),這樣可以分割設定或配置,同時用一個檔案來統一管理。 文件之間使用---(三個連字符)來明確分隔。多個文件的 YAML 檔案範例(multi.yaml)
# 伺服器設定1
---
server:
host: localhost
port: 8080
# 伺服器設定2
---
server:
host: example.com
port: 443這樣寫的 YAML 檔案擁有兩個獨立的資料區塊,需要個別讀取每個區塊。yaml.safe_load_all() 的使用方法
在 PyYAML 中,為了讀取多個文件,準備了 safe_load_all() 函數。這是將檔案內的所有 YAML 文件作為迭代器(可迭代物件)返回的函數。import yaml
with open('multi.yaml', 'r', encoding='utf-8') as f:
documents = yaml.safe_load_all(f)
for doc in documents:
print(doc)執行結果(輸出範例):
{'server': {'host': 'localhost', 'port': 8080}}
{'server': {'host': 'example.com', 'port': 443}}這樣,每個文件可以作為字典逐一取得,透過迴圈處理來靈活運用。注意 safe_load() 的差異
一般的 safe_load() 只讀取第一個文件,因此不適合對應多個文件的檔案。| 函數名 | 對應的 YAML 格式 | 回傳值的形式 |
|---|---|---|
safe_load() | 僅單一文件 | 資料(字典或列表等) |
safe_load_all() | 對應多個文件 | 迭代器(迴圈處理) |
也可以將讀取的文件轉換為列表
有時,可能想要將所有文件作為列表統一取得。在這種情況下,使用以下的list() 即可。with open('multi.yaml', 'r', encoding='utf-8') as f:
documents = list(yaml.safe_load_all(f))這樣,可以以列表形式批次處理,或使用索引指定來存取。注意事項:並非所有 YAML 檔案都對應多個文件
對沒有用--- 分隔的 YAML 檔案使用 safe_load_all() 也沒有問題,但結果只會是單一文件。也就是說,safe_load_all() 是萬能的,但如果不是多個文件,就會和 safe_load() 有相同的行為,請記住這一點。Ad
8. 【補足】使用 YAML 作為設定檔案時的要點
為什麼 YAML 適合用作設定檔案?
YAML 具備 人類易於讀寫的語法 以及 巢狀結構的靈活表現力,因此在許多專案中被採用為「設定檔案」。特別是在使用 Python 開發的應用程式或工具中,使用 YAML 可以讓 設定更容易理解,並提升維護性。 在以下用途中,YAML 非常有用:- Web 應用程式的環境設定(生產/開發/測試)
- 機器學習的超參數設定
- 腳本的行為切換
- API 金鑰等外部依賴資訊的管理(※機密資訊的管理需注意)
實用的 YAML 設定檔案範例
app:
name: MyApp
mode: production
logging:
level: INFO
file: logs/app.log
database:
host: localhost
port: 5432
user: admin
password: secret如此一來,將構成元素依據區段彙整,任何人一看就能了解結構的設定檔案。與 JSON 不同,能自由撰寫註解的這一點在實務上也非常重要。活用巢狀結構的設定階層化
YAML 使用縮排來表現階層,因此也能直覺地表現複雜的設定。例如,想依環境區分設定時,也能如以下方式彙整:env:
dev:
db: dev-db.local
debug: true
prod:
db: prod-db.server
debug: false在 Python 端讀取此設定,即可透過環境變數等自動選擇適當的設定。能以註解明示意圖
YAML 中可以使用# 來撰寫註解。藉此,能將「為什麼是這樣的設定」「何時該變更」等資訊 直接記述在設定檔案內,這是很大的優點。# 應用程式的模式設定(dev, test, production 其中之一)
mode: productionJSON 中無法撰寫註解,因此有無法提供此類補充的限制。執行時讀取 YAML 的程式碼範例(應用)
以下是在 Python 腳本端讀取 YAML 設定並應用到應用程式的範例:import yaml
with open('settings.yaml', 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
app_name = config['app']['name']
mode = config['app']['mode']
db_host = config['database']['host']如此一來,將 YAML 檔案視為 Python 的字典來處理,即可 不需在程式碼中硬編碼設定值 來進行管理。注意事項:機密資訊的處理需十分注意
YAML 雖然對人類來說易於處理,但同時也是 以明文儲存的形式。因此,在 YAML 檔案中記述 API 金鑰或密碼等機密資訊時,需要以下措施:- 使用
.gitignore防止提交到儲存庫 - 與
.env檔案等結合,從 YAML 只進行參照 - 套用加密或存取限制
Ad
9. 常見問題(FAQ)
在本節中,我們將以問答形式說明在 Python 中讀取 YAML 檔案時常見的疑問,以及初學者容易卡住的要點。這些內容在實際專案中使用時也很有幫助,請務必查看。Q1. YAML 和 JSON,在 Python 中哪個比較好處理?
A. YAML 可讀性高,作為設定檔案使用非常方便。 Python 中 JSON 也由標準函式庫支援,但 YAML 因為可以寫註解、結構看起來清楚等原因,在設定檔案用途上,YAML 比較好處理的感覺的人很多。不過,在重視處理速度或資料交換相容性的場合,JSON 也常被偏好。Q2. yaml.load() 不能使用嗎?
A. 原則上使用 safe_load() 比較安全。 load() 雖然彈性高,但可以還原任意的 Python 物件,因此有安全性風險。 如果讀取惡意的 YAML 檔案,可能會執行意想不到的程式碼,因此基本上推薦使用 safe_load()。 如果有必要使用 load() 的話,請像 Loader=yaml.FullLoader 這樣明確指定,並以注重安全性的方式實作。Q3. 讀取的 YAML 內容變成空的(None)是為什麼?
A. 這是 YAML 檔案為空或只有註解時的正常動作。# 這個檔案還沒有設定讀取上述這樣的檔案時,safe_load() 的傳回值會變成 None。這不是異常,而是 YAML 有效的「空資料」。請確認檔案內容是否正確描述。Q4. YAML 檔案中可以像變數一樣重複使用值嗎?
A. YAML 有「錨點」和「別名」這樣的機制。default: &defaults
timeout: 30
retries: 3
service1:
<<: *defaults
host: service1.local
service2:
<<: *defaults
host: service2.local像這樣,使用 & 來記述錨點(定義)、* 來記述別名(參照),就可以在多處重複使用相同的設定。不過,在 PyYAML 中使用這個語法時,可能需要特定版本或 Loader 設定,因此請事先確認動作。Q5. 在 Windows 環境中日文會出現亂碼。該怎麼辦?
A. 在讀取檔案時明確指定編碼即可解決。with open('config.yaml', 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)Windows 的預設文字碼(cp932)無法正確讀取以 UTF-8 寫成的 YAML 檔案。務必明確指定 encoding='utf-8'。Q6. 如果 YAML 檔案分成多個設定區塊要怎麼讀取?
A. 使用safe_load_all() 就可以讀取多個文件。---
app: App1
port: 3000
---
app: App2
port: 4000像這樣的檔案,可以用 yaml.safe_load_all() 逐一處理:with open('multi.yaml', 'r', encoding='utf-8') as f:
for doc in yaml.safe_load_all(f):
print(doc)Ad
10. 總結|掌握Python中的YAML讀取
回顧YAML讀取從基礎到應用的內容
本文針對「想用Python讀取YAML檔案」的人,從基本用法開始,到常見錯誤的處理方法、多重文件以及作為設定檔案的應用範例,一步步詳細說明。 再次總結本文的重點:- PyYAML的安裝:要在Python中處理YAML,首先需要
pip install pyyaml。 - 基本的讀取:
yaml.safe_load()就能安全且簡單地將YAML讀取為字典或清單。 - 錯誤對策:縮排或編碼錯誤是常見的問題。語法檢查和
encoding='utf-8'很重要。 load()的差異:如果重視安全性,應該使用safe_load()。load()必須指定適當的Loader。- 多重文件對應:使用
safe_load_all(),就能靈活處理單一檔案內的多個設定區塊。 - 作為設定檔案的實用性:可讀性與彈性優異的YAML,是Python專案中的設定管理最佳選擇。
今後步驟:更多活用YAML
現在已經掌握YAML的讀取方法,下一步可以透過以下步驟,在實務中進一步活用:- 寫入YAML檔案:使用
yaml.dump()來自動產生設定檔案 - 與JSON的相互轉換:在與Web API或外部服務聯動時很方便
- 與
.env檔案或環境變數併用:建構高安全性的設定管理手法 - 設定的自動載入化:在應用程式啟動時,動態讀取依環境而定的設定檔案



