2016-11-29 5 views
0

Original-YAML-Datei nicht die Erhaltung istruamel.yam wird alle Kommentare

toplevel: 
    #comment1 
    hello: gut 
    #comment2 
    howdy: gut #horizontalcomment 
    #comment3 
    #comment4 
    gets: gut 
    #comment5 

In Python, ich

tat
yml = ruamel.yaml.round_trip_load(yaml_input_str) 
exec("del yml['toplevel']['gets']") 
output_str = ruamel.yaml.round_trip_dump(yml) 

output_str wird

toplevel: 
    #comment1 
    hello: gut 
    #comment2 
    howdy: gut #horizontalcomment 
    #comment5 

und comment3 und comment4 verschwinden. Ist das wie geplant oder ist es ein Fehler?

+0

Blick auf diese Antwort: http://stackoverflow.com/a/38252508/252648. Sieht so aus, als ob die Bearbeitung von Kommentaren nicht vollständig ist. – mangoDrunk

+0

@mangoDrunk Der 'round-trip'-Modus von' ruamel.yaml 'ist in der Lage, eine YAML-Datei (z. B. für die Konfiguration) zu laden, einige Werte zu ändern und die Datei wieder zu schreiben, ohne die Kommentare zu verlieren. Was der Autor, von dem Post, auf den Sie verlinken, versucht, Lügen zu machen, die über seinen Zweck hinausgehen. Es gibt einfach einige Mechanismen in 'ruamel.yaml', die es leichter machen, dieses Ziel zu erreichen, als mit anderen Python-Paketen zu beginnen, in denen Kommentare nicht vollständig erledigt sind (dh jedes andere Python-Paket), einschließlich der Kommentare nicht beim Lesen weggeworfen. – Anthon

Antwort

0

Das ist wie vorgesehen. Aber ist, wie so viel von ramel.yaml, undercoded, in erster Linie als Folge der Faulheit des Paketautors.

Die Kommentare sind mit den Schlüsseln verknüpft, nicht mit einer Position relativ zum Anfang eines Mappings. Aufgrund der Art und Weise, wie der YAML in Token umgewandelt wird, sind die Kommentare mit einem folgenden Schlüssel verknüpft. Das Ergebnis ist, dass, wenn es keinen Schlüssel mehr gibt, der Kommentar noch verfügbar ist, aber nicht mehr ausgegeben wird.

Das Nebeneffekt davon ist, dass, wenn Sie tun:

import sys 
import ruamel.yaml 

yaml_str = """\ 
toplevel: 
    #comment1 
    hello: gut 
    #comment2 
    howdy: gut #horizontalcomment 
    #comment3 
    #comment4 
    gets: gut 
    #comment5 
""" 

data = ruamel.yaml.round_trip_load(yaml_str) 
del data['toplevel']['gets'] 
ruamel.yaml.round_trip_dump(data, sys.stdout) 

Sie Ihre output_str, und dann, wenn Sie folgen, dass durch:

data['toplevel']['gets'] = 42 
ruamel.yaml.round_trip_dump(data, sys.stdout) 

Sie erhalten:

toplevel: 
    #comment1 
    hello: gut 
    #comment2 
    howdy: gut #horizontalcomment 
    #comment3 
    #comment4 
    gets: 42 
    #comment5 

so die Kommentare "magisch" wieder erscheinen.

Wenn Sie die Kommentare zum Ende der verschachtelten Mapping (mit dem Schlüssel 'Toplevel') verschieben möchten, können Sie tun:

comment_tokens = data['toplevel'].ca.items['gets'][1] 
del data['toplevel'].ca.items['gets'] # not strictly necessary 
data['toplevel'].ca.end = comment_tokens 

und Sie erhalten:

toplevel: 
    #comment1 
    hello: gut 
    #comment2 
    howdy: gut #horizontalcomment 
    #comment3 
    #comment4 
    #comment5 

Das ist wahrscheinlich, was Sie in erster Linie erwartet haben.


Das hat mich lässt fragen, warum Sie exec() verwenden, anstatt direkt mit:

del yml['toplevel']['gets'] 
Verwandte Themen