web-dev-qa-db-ja.com

YAMLファイルを解析してPythonオブジェクトに読み込む方法は?

YAMLファイルを解析してPythonオブジェクトに読み込む方法は?

たとえば、このYAML:

Person:
  name: XYZ

このPythonクラスへ:

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

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

ちなみに私はPyYAMLを使用しています。

93
Jamal Khan

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には、ツリーデータを含む辞書が含まれるようになりました。 PrettyPrintを使用してdataMapを印刷すると、次のようになります。

{'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...

そして、「 Convert Python dict to object 」に従ってください。

詳細については、 pyyaml.org および this をご覧ください。

176
user702846

http://pyyaml.org/wiki/PyYAMLDocumentation から:

add_path_resolver(tag, path, kind)は、パスベースの暗黙的なタグリゾルバを追加します。パスは、表現グラフのノードへのパスを形成するキーのリストです。パス要素は、文字列値、整数、またはなしです。ノードの種類は、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
6
user2393229

以下は、ユーザーがvirtualenv(またはシステム)で選択したYAML実装をテストし、load_yaml_fileを適切に定義する1つの方法です。

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:
  https://stackoverflow.com/questions/1550226/python-setup-py-uninstall
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])
0
personal_cloud