ویژگی تصویر

کتابخانه YAML در پایتون — معرفی، کاربردها و مثال‌های عملی

  /  پایتون   /  کتابخانه 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

ویژگیPyYAMLruamel.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 راهکار حرفه‌ای‌تری ارائه می‌دهد. همیشه جنبه‌های امنیتی را در نظر بگیرید و برای ورودی‌های ناشناس از حالت‌های ایمن بارگذاری استفاده کنید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: