Wie kann ich eine YAML-Datei in Python parsen?
Wie kann ich eine YAML-Datei in Python parsen?
Szymon Lipinski
Jon
Die einfachste und reinste Methode, ohne sich auf C-Header zu verlassen, ist PyYaml (Dokumentation), die über installiert werden kann pip install pyyaml
:
#!/usr/bin/env python
import yaml
with open("example.yaml", "r") as stream:
try:
print(yaml.safe_load(stream))
except yaml.YAMLError as exc:
print(exc)
Und das ist es. Eine Fläche yaml.load()
Funktion existiert auch, aber yaml.safe_load()
sollte immer bevorzugt werden, um die Möglichkeit der Ausführung willkürlichen Codes zu vermeiden. Es sei denn, Sie benötigen explizit die Verwendung der willkürlichen Objektserialisierung/-deserialisierung safe_load
.
Beachten Sie, dass das PyYaml-Projekt Versionen bis zum unterstützt YAML 1.1-Spezifikation. Wenn YAML 1.2-Spezifikation Unterstützung benötigt wird, siehe ruamel.yaml wie in dieser Antwort erwähnt.
Außerdem könnten Sie auch einen Drop-in-Ersatz für pyyaml verwenden, der Ihre yaml-Datei in Ordnung hält so wie du es hattestgenannt oyaml. Aussicht synk von oyaml hier
-
Ich würde hinzufügen, dass es besser ist, es zu verwenden, es sei denn, Sie möchten beliebige Objekte serialisieren/deserialisieren
yaml.safe_load
da es keinen beliebigen Code aus der YAML-Datei ausführen kann.– ternärer Operator
7. März 2014 um 8:58 Uhr
-
Yaml yaml = new Yaml(); Objekt obj = yaml.load(“a: 1\nb: 2\nc:\n – aaa\n – bbb”);
– MayTheSchwartzBeWithYou
15. Juli 2014 um 11:01 Uhr
-
Ich mag den Artikel von Moose: martin-thoma.com/configuration-files-in-python
– SaurabhM
19. August 2015 um 2:28 Uhr
-
Möglicherweise müssen Sie zuerst das PyYAML-Paket installieren
pip install pyyaml
siehe diesen Beitrag für weitere Optionen stackoverflow.com/questions/14261614/…– Romain
26. September 2018 um 9:03 Uhr
-
Was ist der Sinn des Erfassens der Ausnahme in diesem Beispiel? Es wird sowieso gedruckt und macht das Beispiel nur komplizierter.
– nichts101
22. Januar 2019 um 23:05 Uhr
Martin Thomas
Lesen & Schreiben von YAML-Dateien mit Python 2+3 (und Unicode)
# -*- coding: utf-8 -*-
import yaml
import io
# Define data
data = {
'a list': [
1,
42,
3.141,
1337,
'help',
u'€'
],
'a string': 'bla',
'another dict': {
'foo': 'bar',
'key': 'value',
'the answer': 42
}
}
# Write YAML file
with io.open('data.yaml', 'w', encoding='utf8') as outfile:
yaml.dump(data, outfile, default_flow_style=False, allow_unicode=True)
# Read YAML file
with open("data.yaml", 'r') as stream:
data_loaded = yaml.safe_load(stream)
print(data == data_loaded)
YAML-Datei erstellt
a list:
- 1
- 42
- 3.141
- 1337
- help
- €
a string: bla
another dict:
foo: bar
key: value
the answer: 42
Gängige Dateiendungen
.yml
und .yaml
Alternativen
- CSV: Supereinfaches Format (Lesen & Schreiben)
- JSON: Gut zum Schreiben von menschenlesbaren Daten; SEHR häufig verwendet (Lesen & Schreiben)
- YAML: YAML ist eine Obermenge von JSON, aber einfacher zu lesen (Lesen & Schreiben, Vergleich von JSON und YAML)
- pickle: Ein Python-Serialisierungsformat (Lesen & Schreiben) ⚠️ Die Verwendung von Pickle mit Dateien von Drittanbietern birgt ein unkontrollierbares Risiko der Ausführung willkürlichen Codes.
- MessagePack (Python-Paket): Kompaktere Darstellung (Lesen & Schreiben)
- HDF5 (Python-Paket): Nett für Matrizen (Lesen & Schreiben)
- XML: existiert auch *seufz* (lesen & schreiben)
Für Ihre Bewerbung könnten folgende Punkte wichtig sein:
- Unterstützung durch andere Programmiersprachen
- Lese- / Schreibleistung
- Kompaktheit (Dateigröße)
Siehe auch: Vergleich von Datenserialisierungsformaten
Falls Sie eher nach einer Möglichkeit suchen, Konfigurationsdateien zu erstellen, sollten Sie vielleicht meinen kurzen Artikel lesen Konfigurationsdateien in Python
-
Welche Kodierung hat die Datei? Bist du sicher, dass es utf-8 kodiert ist?
– Martin Thoma
8. August 2019 um 21:27 Uhr
-
Danke für den Vorschlag. Meine Datei hat utf-8-Kodierung. Ich musste Ihre Codezeile ändern
io.open(doc_name, 'r', encoding='utf8')
um das Sonderzeichen zu lesen. YAML-Version 0.1.7– Wolke Cho
8. August 2019 um 21:53 Uhr
-
Sie können die integrierte verwenden
open(doc_name, ..., encodung='utf8')
zum Lesen und Schreiben, ohne Importio
.– Fingerfertigkeit
13. August 2019 um 9:29 Uhr
-
Sie nutzen
import yaml
, aber das ist kein eingebautes Modul, und Sie geben nicht an, um welches Paket es sich handelt. Betriebimport yaml
bei einer neuen Python3-Installation führt zuModuleNotFoundError: No module named 'yaml'
– Cowlinator
19. November 2019 um 0:05 Uhr
-
@bob Ich habe die Warnung hinzugefügt.
– Martin Thoma
26. Mai um 17:36 Uhr
Anton
Wenn Sie YAML haben, das dem entspricht YAML 1.2-Spezifikation (veröffentlicht 2009) dann sollten Sie verwenden ruamel.yaml (Haftungsausschluss: Ich bin der Autor dieses Pakets). Es ist im Wesentlichen eine Obermenge von PyYAML, die den größten Teil von YAML 1.1 (ab 2005) unterstützt.
Wenn Sie Ihre Kommentare beim Roundtrip beibehalten möchten, sollten Sie auf jeden Fall ruamel.yaml verwenden.
Das Upgrade von @Jons Beispiel ist einfach:
import ruamel.yaml as yaml
with open("example.yaml") as stream:
try:
print(yaml.safe_load(stream))
except yaml.YAMLError as exc:
print(exc)
Verwenden safe_load()
es sei denn, Sie haben wirklich die volle Kontrolle über die Eingabe, brauchen sie (selten der Fall) und wissen, was Sie tun.
Wenn Sie pathlib verwenden Path
Zum Bearbeiten von Dateien verwenden Sie besser die neue API, die ruamel.yaml bietet:
from ruamel.yaml import YAML
from pathlib import Path
path = Path('example.yaml')
yaml = YAML(typ='safe')
data = yaml.load(path)
-
Hallo @Anthon. Ich habe Ruamel’s verwendet, habe aber ein Problem mit Dokumenten, die nicht ASCII-konform sind (
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 926: ordinal not in range(128)
). Ich habe versucht, yaml.encoding auf utf-8 zu setzen, hat aber nicht funktioniert, da die Lademethode in YAML immer noch ascii_decode verwendet. Ist das ein Fehler?– SnwBr
7. Januar 2020 um 17:53 Uhr
Kumpel
Installieren Sie zuerst pyyaml mit pip3.
Importieren Sie dann das yaml-Modul und laden Sie die Datei in ein Wörterbuch namens „my_dict“:
import yaml
with open('filename.yaml') as f:
my_dict = yaml.safe_load(f)
Das ist alles, was Sie brauchen. Jetzt befindet sich die gesamte Yaml-Datei im Wörterbuch „my_dict“.
Prashanth Sams
Beispiel:
defaults.yaml
url: https://www.google.com
Umgebung.py
from ruamel import yaml
data = yaml.safe_load(open('defaults.yaml'))
data['url']
-
Ist es sicher, den Stream nicht zu schließen?
– qrtLs
31. August 2019 um 15:15 Uhr
-
Ich dachte schon, aber ist es das? verwandt: stackoverflow.com/questions/49512990/…
– J Kluseczka
23. Januar 2021 um 23:02 Uhr
-
@qrtLs Es ist definitiv nicht sicher. Sie sollten den Deskriptor jedes Mal explizit schließen, und dies hat einige Gründe: stackoverflow.com/a/25070939/3338479
– lucidyan
14. Juli 2021 um 21:19 Uhr
Rinkush Sharda
So greifen Sie auf ein beliebiges Element einer Liste in einer YAML-Datei zu:
global:
registry:
url: dtr-:5000/
repoPath:
dbConnectionString: jdbc:oracle:thin:@x.x.x.x:1521:abcd
Sie können das folgende Python-Skript verwenden:
import yaml
with open("/some/path/to/yaml.file", 'r') as f:
valuesYaml = yaml.load(f, Loader=yaml.FullLoader)
print(valuesYaml['global']['dbConnectionString'])
-
Ist es sicher, den Stream nicht zu schließen?
– qrtLs
31. August 2019 um 15:15 Uhr
-
Ich dachte schon, aber ist es das? verwandt: stackoverflow.com/questions/49512990/…
– J Kluseczka
23. Januar 2021 um 23:02 Uhr
-
@qrtLs Es ist definitiv nicht sicher. Sie sollten den Deskriptor jedes Mal explizit schließen, und dies hat einige Gründe: stackoverflow.com/a/25070939/3338479
– lucidyan
14. Juli 2021 um 21:19 Uhr
ich benutze ruamel.yaml. Details & Debatte hier.
from ruamel import yaml
with open(filename, 'r') as fp:
read_data = yaml.load(fp)
Benutzung von ruamel.yaml ist (mit einigen einfach lösbaren Problemen) mit alten Verwendungen von PyYAML kompatibel und kann, wie in dem von mir bereitgestellten Link angegeben, verwendet werden
from ruamel import yaml
Anstatt von
import yaml
und es wird die meisten Ihrer Probleme beheben.
BEARBEITEN: PyYAML ist nicht tot, wie sich herausstellt, es wird nur an einem anderen Ort gepflegt.
-
@Oleksander: PyYaml hat Commits in den letzten 7 Monaten und das letzte geschlossene Problem liegt 12 Tage zurück. Können Sie bitte „längst tot“ definieren?
– Abalter
20. März 2018 um 0:18 Uhr
-
@abalter Ich entschuldige mich, anscheinend habe ich die Informationen von ihrer offiziellen Website oder dem Post hier http://stackoverflow.com/a/36760452/5510526
– Oleksandr Selentsov
20. März 2018 um 16:48 Uhr
-
@OleksandrZelentsov Ich kann die Verwirrung sehen. Es gab eine laaange Zeit, in der es tot war. github.com/yaml/pyyaml/graphs/contributors. Ihre Website IST jedoch online und zeigt Veröffentlichungen, die NACH dem SO-Post veröffentlicht wurden und sich auf PyYamls Tod beziehen. Es ist also fair zu sagen, dass es zu diesem Zeitpunkt noch lebt, obwohl seine Richtung relativ zu Ruamel eindeutig ungewiss ist. Außerdem gab es hier eine lange Diskussion mit den letzten Beiträgen. Ich habe einen Kommentar hinzugefügt, und jetzt ist meiner der einzige. Ich glaube, ich verstehe nicht, wie geschlossene Probleme funktionieren. github.com/yaml/pyyaml/issues/145
– Abalter
20. März 2018 um 17:52 Uhr
-
@abalter FWIW, als diese Antwort gepostet wurde, gab es in der Vergangenheit insgesamt 9 Commits … knapp 7 Jahre. Eines davon war eine automatisierte “Korrektur” für schlechte Grammatik. Zwei beinhalteten die Veröffentlichung einer kaum veränderten neuen Version. Der Rest waren relativ kleine Änderungen, die meistens vorgenommen wurden fünf Jahre vor der Antwort. Alle außer der automatisierten Korrektur wurden von einer Person durchgeführt. Ich würde diese Antwort nicht hart beurteilen, weil sie PyYAML als “längst tot” bezeichnet hat.
– Nik
14. Juni 2019 um 15:01 Uhr