Parsen YAML und übernehmen einen bestimmten Weg ist immer ein String
Frage
Ich bin mit dem YAML-Parser von http://pyyaml.org und ich möchte es immer bestimmte Felder zu interpretieren, wie string, aber ich kann nicht herausfinden, wie add_path_resolver () funktioniert.
Zum Beispiel: Der Parser geht davon aus, dass die "Version" ist ein float:
network:
- name: apple
- name: orange
version: 2.3
site: banana
Einige Dateien haben "Version: 2" (die als int interpretiert wird) oder "Version: 2.3 Alpha". (Die als str interpretiert wird)
Ich möchte, dass sie immer als str interpretiert werden.
.Es scheint, dass yaml.add_path_resolver () sollte mir lassen angeben: „Wenn Sie die Version sehen :, immer es als str interpretieren), aber es ist nicht sehr gut dokumentiert Meine beste Vermutung ist:
yaml.add_path_resolver(u'!root', ['version'], kind=str)
Aber das funktioniert nicht.
Vorschläge, wie meine Version Feld zu bekommen, um immer eine Zeichenfolge sein?
P. S. Hier sind einige Beispiele für verschiedene „Version“ Strings und wie sie interpretiert werden:
(Pdb) import yaml
(Pdb) import pprint
(Pdb) pprint.pprint(yaml.load("---\nnetwork:\n- name: apple\n- name: orange\nversion: 2\nsite: banana"))
{'network': [{'name': 'apple'}, {'name': 'orange'}],
'site': 'banana',
'version': 2}
(Pdb) pprint.pprint(yaml.load("---\nnetwork:\n- name: apple\n- name: orange\nversion: 2.3\nsite: banana"))
{'network': [{'name': 'apple'}, {'name': 'orange'}],
'site': 'banana',
'version': 2.2999999999999998}
(Pdb) pprint.pprint(yaml.load("---\nnetwork:\n- name: apple\n- name: orange\nversion: 2.3 alpha\nsite: banana"))
{'network': [{'name': 'apple'}, {'name': 'orange'}],
'site': 'banana',
'version': '2.3 alpha'}
Lösung
Bei weitem die einfachste Lösung hierfür ist nicht die grundlegende .load()
verwenden (was nicht sicher ist sowieso), aber es mit Loader=BaseLoader
verwenden, die Lasten jeder skalare als String:
import yaml
yaml_str = """\
network:
- name: apple
- name: orange
version: 2.3
old: 2
site: banana
"""
data = yaml.load(yaml_str, Loader=yaml.BaseLoader)
print(data)
gibt:
{'network': [{'name': 'apple'}, {'name': 'orange'}], 'version': '2.3', 'old': '2', 'site': 'banana'}
Andere Tipps
Von der Stromquelle:
# Note: `add_path_resolver` is experimental. The API could be changed.
Es scheint, dass es nicht vollständig ist (noch?). Die Syntax, dass würde Arbeit (soweit ich das beurteilen kann) ist:
yaml.add_path_resolver(u'tag:yaml.org,2002:str', ['version'], yaml.ScalarNode)
Es ist jedoch nicht der Fall.
Es scheint, dass der implizite Typ Resolver zuerst geprüft werden, und wenn man Streichhölzer, es prüft dann nie die benutzerdefinierten Resolver. Siehe resolver.py für weitere Einzelheiten (Look für die Funktion resolve
).
Ich schlage vor, Ihren version
Eintrag
version: !!str 2.3
Dies wird immer zwingt es in einen String.