Comment analyser/lire un fichier YAML dans un objet Python?
Par exemple, ce YAML:
Person:
name: XYZ
Pour cette classe Python:
class Person(yaml.YAMLObject):
yaml_tag = 'Person'
def __init__(self, name):
self.name = name
J'utilise PyYAML au fait.
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'arborescence. Si vous imprimez dataMap
avec 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'}}}
Nous avons donc vu comment insérer des données dans notre programme Python. La sauvegarde des données est tout aussi simple:
with open('newtree.yaml', "w") as f:
yaml.dump(dataMap, f)
Vous avez un dictionnaire et vous devez maintenant le convertir en objet Python:
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
Ensuite, vous pouvez utiliser:
>>> args = your YAML dictionary
>>> s = Struct(**args)
>>> s
<__main__.Struct instance at 0x01D6A738>
>>> s...
et suivez " Convert Python dict to object ".
Pour plus d'informations, vous pouvez consulter pyyaml.org et this .
De http://pyyaml.org/wiki/PyYAMLDocumentation :
add_path_resolver(tag, path, kind)
ajoute un résolveur de balise implicite basé sur le chemin. Un chemin est une liste de clés qui forment un chemin vers un nœud dans le graphique de représentation. Les éléments de chemins peuvent être des valeurs de chaîne, des entiers ou aucun. Le type de nœud peut être str, list, dict ou 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
Voici un moyen de tester quelle implémentation YAML l'utilisateur a sélectionnée sur virtualenv (ou le système), puis de définir load_yaml_file
correctement:
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])