Как разобрать / прочитать файл YAML в объект Python? - PullRequest
92 голосов
/ 29 июля 2011

Как разобрать / прочитать файл YAML в объект Python?

Например, этот YAML:

Person:
  name: XYZ

В этот класс Python:

class Person(yaml.YAMLObject):
  yaml_tag = 'Person'

  def __init__(self, name):
    self.name = name

Кстати, я использую PyYAML.

Ответы [ 3 ]

172 голосов
/ 29 июля 2011

Если ваш файл YAML выглядит так:

# tree format
treeroot:
    branch1:
        name: Node 1
        branch1-1:
            name: Node 1-1
    branch2:
        name: Node 2
        branch2-1:
            name: Node 2-1

И вы установили PyYAML так:

pip install PyYAML

И код Python выглядит следующим образом:

import yaml
with open('tree.yaml') as f:
    # use safe_load instead load
    dataMap = yaml.safe_load(f)

Переменная dataMap теперь содержит словарь с данными дерева.Если вы напечатаете dataMap с помощью PrettyPrint, вы получите что-то вроде:

{'treeroot': {'branch1': {'branch1-1': {'name': 'Node 1-1'},
    'name': 'Node 1'},
    'branch2': {'branch2-1': {'name': 'Node 2-1'},
    'name': 'Node 2'}}}

Итак, теперь мы увидели, как получить данные в нашу программу Python.Сохранение данных так же просто:

with open('newtree.yaml', "w") as f:
    yaml.dump(dataMap, f)

У вас есть словарь, и теперь вам нужно преобразовать его в объект Python:

class Struct:
    def __init__(self, **entries): 
        self.__dict__.update(entries)

Затем вы можете использовать:

>>> args = your YAML dictionary
>>> s = Struct(**args)
>>> s
<__main__.Struct instance at 0x01D6A738>
>>> s...

и следуйте инструкциям « Преобразовать Python dict в объект ».

Для получения дополнительной информации вы можете посмотреть pyyaml.org и this .

6 голосов
/ 07 февраля 2016

С http://pyyaml.org/wiki/PyYAMLDocumentation:

add_path_resolver(tag, path, kind) добавляет основанный на пути распознаватель неявных тегов.Путь - это список ключей, которые формируют путь к узлу в графе представления.Элементы paths могут быть строковыми значениями, целыми числами или None.Тип узла может быть str, list, dict или None.

#!/usr/bin/env python
import yaml

class Person(yaml.YAMLObject):
  yaml_tag = '!person'

  def __init__(self, name):
    self.name = name

yaml.add_path_resolver('!person', ['Person'], dict)

data = yaml.load("""
Person:
  name: XYZ
""")

print data
# {'Person': <__main__.Person object at 0x7f2b251ceb10>}

print data['Person'].name
# XYZ
0 голосов
/ 18 сентября 2017

Вот один из способов проверить, какую реализацию YAML выбрал пользователь в virtualenv (или системе), а затем определить load_yaml_file соответствующим образом:

load_yaml_file = None

if not load_yaml_file:
    try:
        import yaml
        load_yaml_file = lambda fn: yaml.load(open(fn))
    except:
        pass

if not load_yaml_file:
    import commands, json
    if commands.getstatusoutput('ruby --version')[0] == 0:
        def load_yaml_file(fn):
            ruby = "puts YAML.load_file('%s').to_json" % fn
            j = commands.getstatusoutput('ruby -ryaml -rjson -e "%s"' % ruby)
            return json.loads(j[1])

if not load_yaml_file:
    import os, sys
    print """
ERROR: %s requires ruby or python-yaml  to be installed.

apt-get install ruby

  OR

apt-get install python-yaml

  OR

Demonstrate your mastery of Python by using pip.
Please research the latest pip-based install steps for python-yaml.
Usually something like this works:
   apt-get install epel-release
   apt-get install python-pip
   apt-get install libyaml-cpp-dev
   python2.7 /usr/bin/pip install pyyaml
Notes:
Non-base library (yaml) should never be installed outside a virtualenv.
"pip install" is permanent:
  /1289096/python-setup-py-udalit
Beware when using pip within an aptitude or RPM script.
  Pip might not play by all the rules.
  Your installation may be permanent.
Ruby is 7X faster at loading large YAML files.
pip could ruin your life.
  https://stackoverflow.com/questions/46326059/
  https://stackoverflow.com/questions/36410756/
  https://stackoverflow.com/questions/8022240/
Never use PyYaml in numerical applications.
  https://stackoverflow.com/questions/30458977/
If you are working for a Fortune 500 company, your choices are
1. Ask for either the "ruby" package or the "python-yaml"
package. Asking for Ruby is more likely to get a fast answer.
2. Work in a VM. I highly recommend Vagrant for setting it up.

""" % sys.argv[0]
    os._exit(4)


# test
import sys
print load_yaml_file(sys.argv[1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...