22.12.09

Python + YAML

Зачем это, собственно?

Для конфигов. Писать конфиги на питоне и импортить, на мой взгляд, лучший вариант. Но это не всегда удобно. Типичный пример: нужно загрузить конфиг из родительской папки. Вариант решения - не импортить, хранить в текстовом формате, читать и парсить.

Конечно, хочется парсить автоматом. Да ещё, чтобы сам конфиг был читабельным. Варианты:

  • XML: избыточный синтаксис, неудобный парсинг
  • INI: ConfigParser - это просто пиздец, наследие винды, не иначе
  • CSV: удобно, но требует специального редактора
  • JSON: почти хорошо, но кое-чего нет и синтаксис немного избыточен
  • YAML: наш победитель :)

По сути yaml - это расширение json. Или json подмножество yaml :)

Как это работает

Для начала ставим пакет. Я подобные простенькие вещи ставлю глобально. Например, так:

sudo aptitude install python-yaml

А дальше всё стандартно:

>>> import yaml
>>> yaml.load('[1, a, false]')  # парсим yaml-строку
[1, 'a', False]
>>> yaml.dump([2, 'b', None])  # дампим в yaml-строку
'[2, b, null]\n'

Можно парсить данные прямо из файла:

cfg = yaml.load(open('test.yaml'))

Например, из такого файла test.yaml:

# Простые типы, а это камент, кстати :)
word: Строка    # без кавычек удобно
num: 2009       # число
none: null      # None
bool: true      # Bool

# Список одной строкой
lst1: [буквы, 123, null]

# Многострочный вариант списка
lst2:
    - буквы   # тут возможны каменты
    # и тут тоже
    - 123
    - null

# Словарь в одну строку
dic1: {word : буквы, num : 123, none : null}

# Многострочный словарь
dic2:
    word: буквы
    num: 123
    none: null

# Длинная строка, переносы удаляются
big_str1: >
    Тру
    лю
    лю

# Длинная строка, переносы сохраняются
big_str2: |
    Тра
    ля
    ля

# Вложенности
langs:
    - XML:
        читабельность: никакая
        использование: мерзкие парсеры
        назначение: обмен данными
    - YAML:
        читабельность: высокая
        использование: святая простота
        назначение: конфиги

Получится такая структура данных:

{
    'word' : u'Строка',
    'num'  : 2009,
    'none' : None,
    'bool' : True,

    'lst1' : [u'Строка', 123, None],
    'lst2' : [u'Строка', 123, None],

    'dic1' : {'none' : None, 'num': 123, 'word' : u'буквы'},
    'dic2' : {'none' : None, 'num': 123, 'word' : u'буквы'},

    'big_str1' : u'Тра ля ля\n',
    'big_str2' : u'Тру\nля\nля\n',

    'langs': {
        'XML': {
            u'читабельность' : u'никакая',
            u'использование' : u'мерзкие парсеры',
            u'назначение'    : u'обмен данными',
        },
        'YAML': {
            u'читабельность' : u'высокая',
            u'использование' : u'святая простота',
            u'назначение'    : u'конфиги',
        }
    },
}

Вот, собственно, и всё чем сам пользуюсь. Но это не все возможности yaml, и желающие изъебнуться и здесь найдут чем позабавиться :)

1 коммент.:

RD комментирует...

Браво! Спасибо, очень понятно и наглядно.