Wie kann ich eine YAML-Datei in Python parsen?

Lesezeit: 7 Minuten

Benutzer-Avatar
Szymon Lipinski

Wie kann ich eine YAML-Datei in Python parsen?

Benutzer-Avatar
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 pyyamlsiehe 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

Benutzer-Avatar
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 Import io.

    – 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. Betrieb import yaml bei einer neuen Python3-Installation führt zu ModuleNotFoundError: 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

Benutzer-Avatar
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

Benutzer-Avatar
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“.

Benutzer-Avatar
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


Benutzer-Avatar
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

1142980cookie-checkWie kann ich eine YAML-Datei in Python parsen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy