1105 Stimmen

Wie kann ich eine YAML-Datei in Python parsen?

Wie kann ich eine YAML-Datei in Python parsen?

12voto

Prashanth Sams Punkte 15800

Exemple :


defaults.yaml

url: https://www.google.com

Umgebung.py

from ruamel import yaml

data = yaml.safe_load(open('defaults.yaml'))
data['url']

1 Stimmen

Ist es sicher, den Stream nicht zu schließen?

0 Stimmen

Ich dachte, das ist es, aber ist es das? verwandt: stackoverflow.com/questions/49512990/

0 Stimmen

@qrtLs Es ist definitiv nicht sicher. Sie sollten den Deskriptor jedes Mal explizit schließen und das hat einige Gründe: stackoverflow.com/a/25070939/3338479

2voto

Ich benutze ruamel.yaml . Details & Debatte aquí .

from ruamel import yaml

with open(filename, 'r') as fp:
    read_data = yaml.load(fp)

Verwendung von ruamel.yaml ist (mit einigen einfachen lösbaren Problemen) mit alten Verwendungen von PyYAML kompatibel, und wie in dem von mir angegebenen Link angegeben, verwenden Sie

from ruamel import yaml

anstelle von

import yaml

und es wird die meisten Ihrer Probleme lösen.

エディテージ : PyYAML ist nicht tot, wie sich herausstellt, es wird nur an einem anderen Ort gepflegt.

0 Stimmen

@Oleksander: PyYaml hat Commits in den letzten 7 Monaten, und das letzte geschlossene Issue ist 12 Tage her. Können Sie bitte "lange tot" definieren?

0 Stimmen

@abalter Ich entschuldige mich, anscheinend habe ich die Informationen von der offiziellen Website oder aus dem Beitrag hier stackoverflow.com/a/36760452/5510526

0 Stimmen

@OleksandrZelentsov Ich kann die Verwirrung verstehen. Es gab eine laaaange Zeit, in der sie tot war. github.com/yaml/pyyaml/graphs/contributors . Ihre Website ist jedoch vorhanden und zeigt Veröffentlichungen, die NACH dem SO-Posting über den Untergang von PyYaml veröffentlicht wurden. So ist es fair zu sagen, dass zu diesem Zeitpunkt ist es noch am Leben, obwohl es die Richtung relativ zu ruamel ist eindeutig ungewiss. ALSO, es gab hier eine lange Diskussion mit aktuellen Beiträgen. Ich habe einen Kommentar hinzugefügt, und jetzt ist meiner der einzige. Ich schätze, ich verstehe nicht, wie geschlossene Themen funktionieren. github.com/yaml/pyyaml/issues/145

1voto

Didlly Punkte 85

Dafür habe ich ein eigenes Skript erstellt. Sie können es gerne verwenden, solange Sie die Namensnennung beibehalten. Es geht davon aus, dass jede Ebene um 2 Leerzeichen mehr eingerückt ist als die letzte Ebene.

# © didlly AGPL-3.0 License - github.com/didlly

def is_float(string):
    try:
        float(string)
        return True
    except ValueError:
        return False

def is_integer(string):
    try:
        int(string)
        return True
    except ValueError:
        return False

def load(path: str) -> dict:
    """A procedure which converts the yaml file at the path specified into a dictionary.

    Args:
        path (str): The path of the yaml file.

    Returns:
        config (dict): The yaml file in dictionary form.
    """

    with open(path, "r") as yaml:
        levels = []
        data = {}
        indentation_str = ""

        for line in yaml.readlines():
            if line.replace(line.lstrip(), '') != "" and indentation_str == "":
                indentation_str = line.replace(line.lstrip(), '')
            if line.strip() == "":
                continue
            elif line.rstrip()[-1] == ":":
                if len(line.replace(line.strip(), '')) // 2 < len(levels):
                    levels[len(line.replace(line.strip(), '')) // 2] = f"['{line.strip()[:-1]}']"
                else:
                    levels.append(f"['{line.strip()[:-1]}']")
                exec(f"data{''.join(str(i) for i in levels[:line.replace(line.lstrip(), '').count(indentation_str) if indentation_str != '' else 0])}['{line.strip()[:-1]}']" + " = {}")

                continue

            value = line.split(":")[-1].strip()

            if is_float(value) or is_integer(value) or value == "True" or value == "False":
                exec(f"data{'' if line == line.strip() else ''.join(str(i) for i in levels[:line.replace(line.lstrip(), '').count(indentation_str) if indentation_str != '' else 0])}['{line.split(':')[0].strip()}'] = {value}")

            else:
                exec(f"data{'' if line == line.strip() else ''.join(str(i) for i in levels[:line.replace(line.lstrip(), '').count(indentation_str) if indentation_str != '' else 0])}['{line.split(':')[0].strip()}'] = '{value}'")

    return data

print(load("config.yml"))

Beispiel

config.yml

level 0 value: 0

level 1:
  level 1 value: 1
  level 2:
    level 2 value: 2

level 1 2:
  level 1 2 value: 1 2
  level 2 2:
    level 2 2 value: 2 2

Ausgabe

{'level 0 value': 0, 'level 1': {'level 1 value': 1, 'level 2': {'level 2 value': 2}}, 'level 1 2': {'level 1 2 value': '1 2', 'level 2 2': {'level 2 2 value': 2 2}}}

0 Stimmen

Das ist so cool! Aber ich arbeite nicht mit Listen wie one:\n - two\n - three

0voto

#!/usr/bin/env python

import sys
import yaml

def main(argv):

    with open(argv[0]) as stream:
        try:
            #print(yaml.load(stream))
            return 0
        except yaml.YAMLError as exc:
            print(exc)
            return 1

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

3 Stimmen

Dieser Code tut eigentlich nichts. Wollten Sie den Code auskommentieren?

0 Stimmen

Ich denke, es erwartet Eingabe. d.h. Python main.py example.yaml. und vielleicht print(yaml.safe_load(stream)) für den Druck?

-2voto

Arpan Saini Punkte 3235

Read_yaml_file Funktion, die alle Daten in ein Wörterbuch zurückgibt.

def read_yaml_file(full_path=None, relative_path=None):
    if relative_path is not None:
        resource_file_location_local = ProjectPaths.get_project_root_path() + relative_path
    else:
        resource_file_location_local = full_path

    with open(resource_file_location_local, 'r') as stream:
        try:
            file_artifacts = yaml.safe_load(stream)
        except yaml.YAMLError as exc:
            print(exc)
    return dict(file_artifacts.items())

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X