はじめに
pythonでの基本的なYAMLの読み書きを解説します。
環境: python 3.12
ライブラリ
pythonでYAMLを読み書きするには、基本はPyYAML
(6.0.2)を使います。
ただし、PyYAMLはYAMLのv1.1までしか対応していないため、v1.2で書かれたYAMLを読む別のライブラリが必要です。
ドキュメント: https://pyyaml.org/wiki/PyYAMLDocumentation
使用例
読み込み
基本
import yaml
with open('document.yaml', encoding='utf-8')as f:
document = yaml.safe_load(f)
複数のドキュメントが含まれているとき
イテレータが返ります。
import yaml
with open('documents.yaml', encoding='utf-8')as f:
documents = list(yaml.safe_load_all(f))
書き込み
基本
import yaml
document: Person = {
"name": "John Doe",
"age": 30,
"skills": ["Python", "Django", "Machine Learning"],
}
with open('document.yaml', mode='w', encoding='utf-8')as f:
yaml.safe_dump(document, f)
PyYAMLは無指定で書き込んだときはjsonのようなフロースタイルとして書き込みます。
safe_dump
の引数にdefault_flow_style=False
を指定することで、よく見るYAMLのようなブロックスタイルとなります。
日本語等をエスケープしたくない場合にはsafe_dump
の引数にallow_unicode=True
を指定してください。
複数のドキュメントに書き込みたいとき
イテラブル(つまりlistやイテレータ、ジェネレータ)を指定するとその要素ごとに分けられて書き込まれます。
import yaml
documents: list[Person] = [
{"name": "Alice", "age": 28, "skills": ["Java", "Spring", "Docker"]},
{"name": "Bob", "age": 35, "skills": ["Go", "Kubernetes", "AWS"]},
]
with open('documents.yaml', mode='w', encoding='utf-8')as f:
yaml.safe_dump_all(documents, f)
ファイルではなく文字列を読み書きしたい
文字列からの読み込みは、ファイルを渡していた引数にyamlのドキュメントになっている文字列を渡すと文字列を解釈して結果を返します。
文字列への書き込みは、ファイルを渡さないようにすると代わりに文字列を返します。
動作例
コード片全体です。
test.py
# 型付けのため
from collections.abc import Iterator
from typing import TypedDict
import yaml
# 型付けのため
class Person(TypedDict):
name: str
age: int
skills: list[str]
print("書き込み")
document: Person = {
"name": "John Doe",
"age": 30,
"skills": ["Python", "Django", "Machine Learning"],
}
with open('document.yaml', mode='w', encoding='utf-8')as f:
yaml.safe_dump(document, f, allow_unicode=True, default_flow_style=False)
# age: 30
# name: John Doe
# skills:
# - Python
# - Django
# - Machine Learning
print("###")
print("読み込み")
with open('document.yaml', encoding='utf-8')as f:
loaded_document: Person = yaml.safe_load(f)
print(loaded_document)
# {'age': 30, 'name': 'John Doe', 'skills': ['Python', 'Django', 'Machine Learning']}
print("###")
print("書き込み(複数のドキュメント)")
documents: list[Person] = [
{"name": "Alice", "age": 28, "skills": ["Java", "Spring", "Docker"]},
{"name": "Bob", "age": 35, "skills": ["Go", "Kubernetes", "AWS"]},
]
with open('documents.yaml', mode='w', encoding='utf-8') as f:
yaml.safe_dump_all(documents, f, allow_unicode=True, default_flow_style=False)
# age: 28
# name: Alice
# skills:
# - Java
# - Spring
# - Docker
# ---
# age: 35
# name: Bob
# skills:
# - Go
# - Kubernetes
# - AWS
print("###")
print("読み込み(複数のドキュメント)")
with open('documents.yaml', encoding='utf-8') as f:
loaded_documents: list[Person] = list(yaml.safe_load_all(f))
for doc in loaded_documents:
print(doc)
# {'age': 28, 'name': 'Alice', 'skills': ['Java', 'Spring', 'Docker']}
# {'age': 35, 'name': 'Bob', 'skills': ['Go', 'Kubernetes', 'AWS']}
print("###")