کتابخانه yaml در پایتون
YAML (مخفف “YAML Ain’t Markup Language”) یک فرمت متنی انسانخوان است که برای ذخیرهسازی پیکربندیها، سریالیزیشن دادهها و تبادل تنظیمات بین سرویسها بسیار مناسب است. در پایتون، چندین کتابخانه برای کار با YAML وجود دارد که معروفترین آنها PyYAML و ruamel.yaml هستند. در این مقاله به بررسی مفاهیم پایه، نکات امنیتی، مثالهای عملی و راهکارهای پیشرفته میپردازیم.
نصب و شروع سریع
برای نصب PyYAML و ruamel.yaml از pip استفاده کنید:
pip install pyyaml
pip install ruamel.yaml
این دو خط کتابخانههای مرسوم را نصب میکنند. PyYAML برای اکثر استفادهها کفایت میکند؛ اما اگر نیاز به حفظ ترتیب، کامنتها یا round-trip داشته باشید، ruamel.yaml مناسبتر است.
خواندن و نوشتن YAML با PyYAML
import yaml
data = {
'name': 'Ali',
'age': 30,
'skills': ['python', 'yaml', 'docker']
}
# ذخیره کردن در فایل
with open('data.yaml', 'w', encoding='utf-8') as f:
yaml.dump(data, f, allow_unicode=True)
# خواندن از فایل
with open('data.yaml', 'r', encoding='utf-8') as f:
loaded = yaml.safe_load(f)
print(loaded)
در این مثال ابتدا یک دیکشنری ساده ساخته میشود، سپس با yaml.dump آن را در فایل ذخیره میکنیم. آرگومان allow_unicode=True باعث میشود کاراکترهای غیرانگلیسی (مثل فارسی) بهدرستی نوشته شوند. برای بارگذاری از فایل از yaml.safe_load استفاده میکنیم که امنتر از yaml.load است.
تفاوت safe_load و load — نکات امنیتی
هشدار امنیتی: تابع yaml.load در قدیم میتوانست اشیاء پایتون را از YAML بازیابی کند که این خود میتواند منجر به اجرای کد دلخواه شود. بنابراین برای ورودیهایی که منبع مشخص یا امنی ندارند، همیشه از yaml.safe_load استفاده کنید. اگر به قابلیتهای پیشرفتهتر نیاز دارید، از Loader= yaml.FullLoader با آگاهی کامل استفاده نمایید.
نمونه: نگاشت به کلاسهای پایتون (Custom Objects)
import yaml
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def person_representer(dumper, data):
return dumper.represent_mapping('!Person', {'name': data.name, 'age': data.age})
def person_constructor(loader, node):
values = loader.construct_mapping(node)
return Person(values['name'], values['age'])
yaml.add_representer(Person, person_representer)
yaml.add_constructor('!Person', person_constructor)
p = Person('Sara', 25)
serialized = yaml.dump(p)
print(serialized)
loaded = yaml.load(serialized, Loader=yaml.FullLoader)
print(loaded.name, loaded.age)
در این قطعه، نشان میدهیم چگونه یک کلاس پایتون را به YAML تبدیل و مجدداً از آن بازسازی کنیم. از add_representer و add_constructor برای تعریف نگاشتهای دلخواه استفاده شده است. دقت کنید که چنین عملیاتی ریسک امنیتی دارد؛ بنابراین روی دیتاهای ناامن از آن استفاده نکنید.
حفظ ترتیب، کامنتها و Round-Trip با ruamel.yaml
PyYAML ترتیب عناصر را در نسخههای قدیمی حفظ نمیکرد و کامنتها را از بین میبرد. اگر نیاز دارید فایل YAML را ویرایش کنید و ساختار و کامنتهای آن حفظ شود، از ruamel.yaml استفاده کنید:
from ruamel.yaml import YAML
yaml = YAML()
with open('config.yaml', 'r', encoding='utf-8') as f:
data = yaml.load(f)
# تغییر مقدار
data['version'] = 2
with open('config.yaml', 'w', encoding='utf-8') as f:
yaml.dump(data, f)
ruamel.yaml قابلیت round-trip را دارد؛ یعنی وقتی فایلی را میخوانید و سپس تغییر میدهید، ترتیب و کامنتها به صورت اولیه حفظ میشوند که برای فایلهای پیکربندی مهم حیاتی است.
کار با anchor و alias در YAML
import yaml
text = """
defaults: &defaults
timeout: 30
retries: 3
server1:
<<: *defaults
host: server1.example.com
server2:
<<: *defaults
host: server2.example.com
"""
data = yaml.safe_load(text)
print(data)
در این مثال از anchor (&defaults) و alias (*defaults) استفاده شده است تا تنظیمات مشترک بین چند بخش بهصورت DRY تعریف شود. PyYAML این الگو را به صورت دیکشنری پایتون برمیگرداند.
مقایسه سریع: PyYAML در برابر ruamel.yaml
| ویژگی | PyYAML | ruamel.yaml |
|---|---|---|
| سادگی | بالا | متوسط |
| حفظ کامنت و order | خیر | بله (round-trip) |
| پشتیبانی از YAML 1.2 | محدود | خوب |
| مناسب برای | کارهای ساده و عمومی | ویرایش پیکربندیها و ابزارهای پیچیده |
نکات بهینهسازی و بهترین روشها
- همیشه برای ورودیهای ناشناس از
safe_loadاستفاده کنید تا از حملات اجرای کد جلوگیری شود. - برای فایلهای بزرگ، از stream خواندن و نوشتن استفاده کنید تا حافظه کمتر مصرف شود.
- اگر نیاز به حفظ کامنتها و ترتیب دارید، از ruamel.yaml بهره ببرید.
- برای تعامل با JSON، از yaml.safe_load و yaml.dump(…, default_flow_style=False) استفاده کنید تا خروجی خواناتر شود.
- برای کار با Unicode از
encoding='utf-8'وallow_unicode=Trueاستفاده کنید.
موارد کاربردی (Use Cases)
- فایلهای پیکربندی اپلیکیشنها (مثلاً در پروژههای Django/Flask یا اسکریپتهای CLI)
- تعریف pipelineها و تنظیمات CI/CD (GitLab CI, GitHub Actions به شکل YAML)
- سریالیزیشن و تبادل مقادیر بین سرویسهای میکروسرویس
- ذخیرهسازی تنظیمات پیشرفته با نیاز به کامنتها (استفاده از ruamel.yaml)
جمعبندی
کتابخانه YAML در پایتون ابزار قدرتمندی برای کار با فایلهای پیکربندی و تبادل دادههاست. برای استفادههای ساده و عمومی PyYAML مناسب و سریع است؛ اما اگر به round-trip، حفظ کامنتها و ترتیب نیاز دارید، ruamel.yaml راهکار حرفهایتری ارائه میدهد. همیشه جنبههای امنیتی را در نظر بگیرید و برای ورودیهای ناشناس از حالتهای ایمن بارگذاری استفاده کنید.
آیا این مطلب برای شما مفید بود ؟




