【问题标题】:How to parse/read a YAML file into a Python object?如何将 YAML 文件解析/读取到 Python 对象中?
【发布时间】:2011-10-15 13:07:48
【问题描述】:

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

例如,这个 YAML:

Person:
  name: XYZ

到这个 Python 类:

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

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

顺便说一句,我正在使用 PyYAML。

【问题讨论】:

  • 我建议使用python-box
  • 如何在 Python 中解析 YAML 文件?与如何将 YAML 文件解析/读取到 Python 对象中绝对不是同一个问题?一般解析和解析成面向对象的结构是两个不同的东西。我正在投票重新开放 - 看看这里的答案有多少赞成......

标签: python parsing yaml


【解决方案1】:

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

【讨论】:

  • @personal_cloud 从不有点强。在 Docker 容器或嵌入式(作为快速示例)中运行的 Python 应用程序可能会选择不使用 virtualenv,因为它是一个额外的层,在容器本身已经提供的之外没有提供任何隔离。
【解决方案2】:

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

【讨论】:

  • 库不应该安装在 virtualenv 之外,注意。
  • 点赞前别忘了sudo apt-get install libyaml-cpp-dev
  • pip 安装是永久的,请注意。 stackoverflow.com/questions/1550226/python-setup-py-uninstal‌​l
  • @personal_cloud virtualenv 很酷,但pip install 不是永久的。有一个pip uninstall,如this answer 中所述,您引用的问题。然后可以使用包管理器恢复原始包。
  • virtualenv 很酷,但pipenv 更酷。
【解决方案3】:

这是测试用户在 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])

【讨论】:

    猜你喜欢
    • 2018-08-08
    • 2010-12-18
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 2023-03-26
    • 2018-02-16
    相关资源
    最近更新 更多