YAML parsing et Python?

Quelle est la meilleure façon de parser un fichier YAML dans un objet Python?

par exemple, ce YAML:

Person:
  name: XYZ

à cette classe de Python:

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

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

au fait, J'utilise PyYAML.

75
demandé sur the Tin Man 2011-07-29 02:36:01

3 réponses

si votre fichier YAML ressemble à ceci:

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

et vous avez installé PyYAML comme ceci:

pip install PyYAML

et le code Python ressemble à ceci:

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

la variable dataMap contient maintenant un dictionnaire avec les données de l'arbre. Si vous imprimez dataMap en utilisant PrettyPrint, vous obtiendrez quelque chose comme:

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

Donc, maintenant nous avons vu comment obtenir des données dans notre programme Python. Enregistrer des données est tout aussi facile:

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

Vous avez un dictionnaire, et maintenant vous devez le convertir en un objet Python:

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

alors vous pouvez utiliser:

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

et suivre " Convertir Python dict pour objet ".

pour plus d'informations, vous pouvez consulter pyyaml.org et ce .

150
répondu user702846 2017-07-28 17:32:30

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

add_path_resolver(tag, path, kind) ajoute un résolveur d'étiquette implicite basé sur le chemin. Un chemin est une liste de clés qui forment un chemin vers un noeud dans le graphe de représentation. Les éléments de chemins peuvent être des valeurs de chaîne, des entiers ou aucun. Le type d'un nœud peut être str, liste, dict, ou Aucun.

#!/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
répondu user2393229 2016-02-07 15:32:12

Voici une façon de tester quelle implémentation YAML L'Utilisateur a sélectionnée sur le virtualenv (ou le système) et ensuite définir load_yaml_file de manière appropriée:

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:
  /q/python-setup-py-uninstall-19907/"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
répondu personal_cloud 2017-09-27 22:07:32