۶ قابلیت YAML که اکثر برنامه‌نویسان از آن‌ها بی‌اطلاع هستند


۲۴ بهمن ۱۳۹۹
۶ قابلیت yaml که اکثر برنامه‌نویسان از آن‌ها بی‌اطلاع هستند

YAML یک فرمت فایل است که معمولا برای data serialization استفاده می‌شود. همچنین پروژه‌های زیاد وجود دارند که از فایل‌های YAML به‌منظور پیکربندی استفاده می‌کنند برای مثال می‌توانیم به Docker-compose، pre-commit, TravisCI، AWS Cloudformation، ESLint، Kubernetes، Ansible اشاره داشته باشیم. بنابراین آشنایی با قابلیت‌های YAML می‌تواند بسیار مفید باشد.

در ابتدا باید بدانید که YAML با توجه به این مقاله بسیاری قابلیت‌های JSON را در خود دارد. هر فایل معتبر JSON نیز یک فایل معتبر YAML است. این یعنی شما تمام نوع‌های متغیر مورد نیاز خود مانند integerها، floatها، stringها، booleanها، null و همچنین sequence‌ها و mapها را در اختیار دارید. به نسبت زبان برنامه‌نویسی که از آن استفاده می‌کنید ممکن است sequence را به‌عنوان array یا list و از map به‌عنوان dictionary استفاده کنید.

یک فایل YAML معمولا به شکل زیر است:

mysql:
  host: localhost
  user: root
  password: something
preprocessing_queue: # Line comments are available!
  - name: preprocessing.scale_and_center
    width: 32
    height: 32
  - preprocessing.dot_reduction
use_anonymous: true

Equivalent Notation

برای پیاده‌سازی فایل‌های YAML روش‌های معادل زیادی وجود دارد:

list_by_dash:
  - foo
  - bar
list_by_square_bracets: [foo, bar]
map_by_indentation:
  foo: bar
  bar: baz
map_by_curly_braces: { foo: bar, bar: baz }
string_no_quotes: Monty Python
string_double_quotes: "Monty Python"
string_single_quotes: 'Monty Python'
bool_english: yes
bool_english_no: no
bool_python: True
bool_json: true

یکی از مواردی که باید به آن توجه داشته باشید:

language: no # ISO 639-1 code for the Norwegian language

این no به‌معنای false است و برای نوشتن no می‌توانید آن را در double quotes یا single quotes بگذارید. البته به‌طور کلی توصیه می‌شود که از true و false برای مقادیر boolean استفاده شود اما در YAML می‌توانید به ۱۱ روش booleanها را مقداردهی کنید.

اگر می‌خواهید از quotes برای stringها استفاده کنید بهتر است از double quotes استفاده شود زیرا برای افراد تازه‌کاری که می‌خواهند با فایل‌های YAML کار کنند قابل درک‌تر است.

البته معادل‌های بسیار زیاد دیگری وجود دارد و همان‌طور که Tom Ritchford اشاره کرده است شاید این معادل‌های بسیار زیاد باعث شود تا فایل‌های YAML انتخابی خطرناک و نامناسب باشند.

Long Strings

disclaimer: >
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  In nec urna pellentesque, imperdiet urna vitae, hendrerit
  odio. Donec porta aliquet laoreet. Sed viverra tempus fringilla.

YAML فوق معادل JSON زیر است:

{ "disclaimer": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In nec urna pellentesque, imperdiet urna vitae, hendrerit odio. Donec porta aliquet laoreet. Sed viverra tempus fringilla." }

Multi-Line String

mail_signature: |
  Martin Thoma
  Tel. +49 123 4567

YAML فوق معادل JSON زیر است:

{ "mail_signature": "Martin Thoma\nTel. +49 123 4567" }

Anchor

email: &emailAddress "info@example.de"
id: *emailAddress

YAML فوق معادل JSON زیر است:

{
    "email": "info@example.de",
    "id": "info@example.de"
}

با استفاده از & یک متغیر با نام emailAddress و مقدار info@example.de تعریف می‌شود و *emailAddress به مقدار متغیر تعریف شده اشاره می‌کند.

شما می‌توانید همین کار را با mapping انجام دهید:

foo: &default_settings
  db:
    host: localhost
    name: main_db
    port: 1337
  email:
    admin: admin@example.com
prod: *default_settings
dev: *default_settings

معادل:

{
    "dev": {
        "db": {
            "host": "localhost",
            "name": "main_db",
            "port": 1337
        },
        "email": {
            "admin": "admin@example.com"
        }
    },
    "foo": {
        "db": {
            "host": "localhost",
            "name": "main_db",
            "port": 1337
        },
        "email": {
            "admin": "admin@example.com"
        }
    },
    "prod": {
        "db": {
            "host": "localhost",
            "name": "main_db",
            "port": 1337
        },
        "email": {
            "admin": "admin@example.com"
        }
    }
}

ممکن است بخواهید که رمزعبور دیتابیس یا هر داده‌ی دیگری را به تنظیمات dev و prod اضافه کنید که با استفاده از merge key << می‌توان این کار را انجام داد.

foo: &default_settings
  db:
    host: localhost
    name: main_db
    port: 1337
  email:
    admin: admin@example.com
prod:
  <<: *default_settings
  app:
    port: 80
dev: *default_settings

YAML فوق معادل JSON زیر است:

{
    "foo": {
        "db": {
            "host": "localhost",
            "name": "main_db",
            "port": 1337
        },
        "email": {
            "admin": "admin@example.com"
        }
    },
    "prod": {
        "app": {
            "port": 80
        },
        "db": {
            "host": "localhost",
            "name": "main_db",
            "port": 1337
        },
        "email": {
            "admin": "admin@example.com"
        }
    },
    "dev": {
        "db": {
            "host": "localhost",
            "name": "main_db",
            "port": 1337
        },
        "email": {
            "admin": "admin@example.com"
        }
    }
}

Type Casting

!! در YAML معنای خاصی دارد و با توجه به این مستندات کوتاه‌ شده‌ی !tag:yaml.org,2002: است.

برای تبدیل نوع متغیر می‌توانید به‌صورت زیر عمل کنید:

price: !!float 42
id: !!str 42

یا در موارد پیچیده‌تر می‌توانیم داده‌ها را به انواع داده‌هایی که در زبان Python تعریف شده‌اند اما در YAML به‌صورت مستقیم وجود ندارند، تبدیل کنیم:

tuple_example: !!python/tuple
  - 1337
  - 42
set_example: !!set { 1337, 42 }
date_example: !!timestamp 2020-12-31

YAML فوق را می‌توان معادلی برای کدهای زیر دانست:

import yaml
import pprint

with open("example.yaml") as fp:
    data = fp.read()

pp = pprint.PrettyPrinter(indent=4)

pased = yaml.unsafe_load(data)
pp.pprint(pased)

که خروجی آن به‌صورت زیر است:

{   'date_example': datetime.date(2020, 12, 31),
    'set_example': set([42, 1337]),
    'tuple_example': (1337, 42)}

در این مثال از تگ مخصوص برای زبان Python یعنی !!python/tuple و برخی تگ‌های استاندارد YAML استفاده شده است. PyYaml اطلاعات بیشتری در این باره ارائه می‌دهد:

## Standard YAML tags
YAML               Python 3
!!null             None
!!bool             bool
!!int              int
!!float            float
!!binary           bytes
!!timestamp        datetime.datetime
!!omap, !!pairs    list of pairs
!!set              set
!!str              str
!!seq              list
!!map              dict## Python-specific tags
YAML               Python 3
!!python/none      None
!!python/bool      bool
!!python/bytes     bytes
!!python/str       str
!!python/unicode   str
!!python/int       int
!!python/long      int
!!python/float     float
!!python/complex   complex
!!python/list      list
!!python/tuple     tuple
!!python/dict      dict## Complex Python tags
!!python/name:module.name         module.name
!!python/module:package.module    package.module
!!python/object:module.cls        module.cls instance
!!python/object/new:module.cls    module.cls instance
!!python/object/apply:module.f    value of f(...)

توجه داشته باشید که load کردن تگ‌های غیر استاندارد، ایمن نیست! اما به‌هرصورت اجرای کدهای دلخواه با !!python/object/apply:module.f امکان‌پذیر است. در PyYaml به yaml.unsafe_load نیاز است تا بتوانید از آن استفاده کنید.

Multiple Documents در یک فایل YAML

شما می‌توانید با استفاده از سه - داکیومنت‌های جداگانه‌ای داشته باشید:

foo: bar
---
fizz: buzz

در Python می‌توانید به‌صورت زیر عمل کنید:

import yaml

with open("example.yaml") as fp:
    data = fp.read()

parsed = yaml.safe_load_all(data) # parsed is a generator

اگر متغیر parsed را به list تبدیل کرده و آن را print کنید، خروجی به شکل زیر خواهد بود:

[{'foo': 'bar'}, {'fizz': 'buzz'}]

توجه داشته باشید که این یک معادل جایگزین برای ایجاد list نیست.

منبع: https://levelup.gitconnected.com/6-yaml-features-most-programmers-dont-know-164762343af3

برچسب‌ها:

خدمات رایگان لیارا

۲.۵ گیگابایت فضای ذخیره‌سازی ابری رایگان

۲.۵ گیگابایت Object Storage سازگار با پروتکل S3 با دیسک‌های SSD به‌صورت رایگان دریافت کنید.

هاست رایگان برای دیتابیس‌

دیتابیس‌های MariaDB، PostgreSQL و Redis را فقط با یک کلیک و به‌صورت رایگان تهیه کنید.

سرویس DNS رایگان

به سادگی دامنه‌تان را اضافه کنید و به صورت رایگان رکورد‌های آن را مدیریت کنید.

۱۰۰ هزار تومان اعتبار اولیه

بعد از ثبت نام در لیارا مبلغ ۱۰۰ هزار تومان اعتبار هدیه دریافت می‌کنید که با توجه به ساعتی بودن هزینه سرویس‌ها، می‌توانید تمامی خدمات پولی را برای چندین هفته رایگان استفاده کنید.

ارسال ۱۰۰ ایمیل تراکنشی رایگان در هر ماه

در سرویس ایمیل لیارا شما می‌توانید تا ۱۰۰ ایمیل رایگان در هر ماه ارسال کنید و فقط برای بیش از آن هزینه پرداخت کنید. (به‌همراه دسترسی SMTP)

هاست رایگان برای انواع وبسایت

تفاوتی ندارد برای وبسایت خود از Node استفاده می‌کنید یا Laravel و Django، در لیارا می‌توانید به صورت کاملا رایگان آن را میزبانی کنید.

توسعه‌دهندگان درباره‌ی ما چه می‌گویند

تجربه کار باliara_cloud@امروز خیلی خوب بود. یکی از سرویس هام رو منتقل کردم روش و راضیم. انقد سریع و جذاب کارم راه افتادم اصن باورم نمیشد! برعکس سرویس های PaaS دیگه با اون همه پیچیدگیشون. دمتون گرم
...

MohammadReza
liara testimonial
keikaavousi

بعد از بسته شدن @fandoghpaas و ناراحتی همه‌مون از اینکه یه سرویس خوب و صادق نمی‌تونه از پس هزینه‌ها بر بیاد، سرویسم رو منتقل کردم به پاس لیارا (https://liara.ir @liara_cloud) . تجربه راحت و خوب. تفاوت‌هایی داشت که کمی کار می‌خواست ولی تا الان کاملا راضی.

jadi
liara testimonial
jadi

یه خسته نباشید باید به تصمیمliara_cloud@بگم،
بعد از چندین روز سرکله زدن با سرویس های مشابه بالاخره تصمیم گرفتم لیارا رو امتحان کنم و باور نمیشه ۱۰ دقیقه بیشتر وقت نبرد،
دمتون گرم.

Arch
liara testimonial
EbadiDev

واسه سرویس PaaS با اختلاف لیارا بهترین رابط کاربری داره و یکی از مزیت‌های سرویس دیتابیس‌شون اینه که خودشون به صورت دوره‌ای بکآپ میگیرن.
...

Ali Najafi
liara testimonial
me_ali_najafi

یکی از کارهای خوبی که جدیداً میکنم اینه که یه دیتابیس روی لیارا میسازم و به پروژه وصل میکنم اینطوری هم خونه و هم محل کار دیتابیس بروز رو دارم و راحت میتونم ادامه بدم کار روliara_cloud@

Navid
liara testimonial
1navid

عاشقliara_cloud@شدم درسته در حد AWS نیست ولی خب تجربه خوبی واسه پروژه های داخل ایران ارائه میده، میتونم رو CD هم اجراش کنم

Amir H Shekari
liara testimonial
vanenshi

همراه شما هستیم

در خصوص سفارش یا استفاده از سرویس‌ها سوالی دارید؟
تلفن واحد فروش:
۰۲۵-۳۳۵۵۷۶۱۹ (روزهای کاری ۹ الی ۱۷)
تلفن واحد فروش: ۳۳۵۵۷۶۱۹-۰۲۵ (روزهای کاری ۹ الی ۱۷)