2016-07-14 10 views
4

Ich habe folgende YAML-Datei:pyyaml ​​und mit Anführungszeichen für Strings nur

--- 
my_vars: 
    my_env: "dev" 
    my_count: 3 

Wenn ich es mit PyYAML lesen und Dump wieder, erhalte ich die folgende Ausgabe:

--- 
my_vars: 
    my_env: dev 
    my_count: 3 

Der Code in Frage:

with open(env_file) as f: 
    env_dict = yaml.load(f) 
    print(yaml.dump(env_dict, indent=4, default_flow_style=False, explicit_start=True)) 

ich die default_style Parameter versucht, mit:

with open(env_file) as f: 
    env_dict = yaml.load(f) 
    print(yaml.dump(env_dict, indent=4, default_flow_style=False, explicit_start=True, default_style='"')) 

Aber jetzt erhalte ich:

--- 
"my_vars": 
    "my_env": "dev" 
    "my_count": !!int "3" 

Was muss ich die ursprüngliche Formatierung zu halten zu tun, ohne in der YAML-Datei keine Annahmen über die Variablennamen machen?

+0

Warum drucken Sie nicht nur die Datei, ist es wichtig, dass Sie das Wörterbuch als für Quelle verwenden, was Sie drucken und nicht die Datei selbst? – Nobilis

+0

Ich werde dem Wörterbuch in Zukunft weitere Schlüssel hinzufügen, aber das Layout muss beibehalten werden. –

Antwort

1

rechts, so stark von this answer leihen, können Sie etwas tun:

import yaml 

# define a custom representer for strings 
def quoted_presenter(dumper, data): 
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"') 

yaml.add_representer(str, quoted_presenter) 


env_file = 'input.txt' 
with open(env_file) as f: 
    env_dict = yaml.load(f) 
    print yaml.dump(env_dict, default_flow_style=False) 

Doch diese Überlastungen es nur auf alle Strings Typen im Wörterbuch, damit es die Schlüssel zitieren werde auch nicht nur die Werte.

Er druckt:

"my_vars": 
    "my_count": 3 
    "my_env": "dev" 

Ist das, was Sie wollen? Nicht sicher, was du unter Variablennamen meinst, meinst du die Schlüssel?

+0

Das hat mir schon sehr geholfen, danke :-) Immer noch nicht sicher, wie ich es nur auf die Werte anwenden kann, nicht auf die Tasten. –

+0

Wenn Sie viel Zeit haben, dann schlage ich eine Reise nach YAML [Dokumentation] (http: // pyyaml.org/wiki/PyYAMLDocumentation # Constructorsrepresentstersresolvers) zum Erstellen von Repräsentanten und dann ein gründliches Lesen der YAML-Tags [hier] (http://www.yaml.org/spec/1.2/spec.html). Es gibt auch [diese Antwort] (http://stackoverflow.com/questions/20805418/pyyaml-dump-format), die eine Abzweigung von PyYaml diskutiert und etwas über das Beibehalten der ursprünglichen Formatierung erwähnt, könnte ebenfalls hilfreich sein. – Nobilis

3

Ich empfehle Ihnen, auf die Verwendung von YAML 1.2 (veröffentlicht 2009) mit dem abwärtskompatiblen ruamel.yaml-Paket zu aktualisieren, anstatt PyYAML zu verwenden, das die meisten von YAML 1.1 (2005) implementiert. (Haftungsausschluss: Ich bin der Autor dieses Pakets).

Dann einfach Sie preserve_quotes=True angeben, wenn rund um die Auslösung des YAML-Datei laden für:

import sys 
import ruamel.yaml 

yaml_str = """\ 
--- 
my_vars: 
    my_env: "dev" # keep "dev" quoted 
    my_count: 3 
""" 

data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True) 
ruamel.yaml.round_trip_dump(data, sys.stdout, explicit_start=True) 

die Ausgänge (einschließlich der erhaltenen Kommentar):

--- 
my_vars: 
    my_env: "dev" # keep "dev" quoted 
    my_count: 3 

Nach dem String Skalare Laden wird sein, Unterklasse von Zeichenketten, um die Quotinfo aufzunehmen, funktioniert aber wie eine normale Zeichenkette für alle anderen Zwecke. Wenn Sie eine solche Zeichenfolge ersetzt werden soll, obwohl (dev-fgw) Sie müssen die Zeichenfolge in dieser Unterklasse geworfen (DoubleQuotedScalarString von ruamel.yaml.scalarstring).

Wenn ruamel.yaml standardmäßig Rundauslöse bewahrt die Reihenfolge (durch Insertion) des Schlüssels.

Verwandte Themen