Wie kann ich eine YAML-Datei in Python parsen?
Ist es sicher, den Stream nicht zu schließen?
@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
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.
@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?
@abalter Ich entschuldige mich, anscheinend habe ich die Informationen von der offiziellen Website oder aus dem Beitrag hier stackoverflow.com/a/36760452/5510526
@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
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"))
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
{'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}}}
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 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.