如何解析/读取YAML文件到Python对象?

时间:2011-07-28 22:36:02

标签: python parsing yaml

如何将YAML文件解析/读取到Python对象中?

例如,这个YAML:

Person:
  name: XYZ

到这个Python类:

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

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

我顺便使用PyYAML。

3 个答案:

答案 0 :(得分:166)

如果您的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.orgthis

答案 1 :(得分:6)

来自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

答案 2 :(得分:0)

这是一种测试用户在virtualenv(或系统)上选择的YAML实现,然后恰当地定义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:
  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])