Frage YAML-Parsing und Python?


Was ist der beste Weg, um eine YAML-Datei in ein Python-Objekt zu analysieren?

Zum Beispiel, diese YAML:

Person:
  name: XYZ

Zu dieser Python-Klasse:

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

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

Ich benutze PyYAML übrigens.


75
2017-07-28 22:36


Ursprung


Antworten:


Wenn Ihre YAML-Datei wie folgt aussieht:

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

Und du hast es installiert PyYAML so was:

pip install PyYAML

Und der Python-Code sieht so aus:

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

Die Variable dataMap Enthält jetzt ein Wörterbuch mit den Baumdaten. Wenn Sie drucken dataMap Mit PrettyPrint erhalten Sie etwas wie:

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

Jetzt haben wir gesehen, wie wir Daten in unser Python-Programm bekommen. Das Speichern von Daten ist genauso einfach:

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

Sie haben ein Wörterbuch und müssen es jetzt in ein Python-Objekt konvertieren:

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

Dann können Sie verwenden:

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

und folgen "Konvertiere Python-Diktat in Objekt".

Für weitere Informationen können Sie sich anschauen pyyaml.org und Dies.


149
2017-07-28 22:49



Von http://pyyaml.org/wiki/PyYAMLDokumentation:

add_path_resolver(tag, path, kind) Fügt einen pfadbasierten impliziten Tag Resolver hinzu. Ein Pfad ist eine Liste von Schlüsseln, die einen Pfad zu einem Knoten im Darstellungsdiagramm bilden. Pfadelemente können Zeichenfolgenwerte, Ganzzahlen oder Keine sein. Die Art eines Knotens kann str, list, dict oder None sein.

#!/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
2018-02-07 15:32



Hier ist eine Möglichkeit zu testen, welche YAML-Implementierung der Benutzer auf dem virtualenv (oder dem System) ausgewählt und dann definiert hat load_yaml_file passend:

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
2017-09-18 20:06