Sie wahrscheinlich einige Representer für die MyObj Klasse Dumping, wie standardmäßig haben (print(yaml.dump(MyObj()))
) mit PyYAML geben Ihnen:
!!python/object:__main__.MyObj {}
PyYAML kann nur mit den Kommentaren in der gewünschten Ausgabe eines: verwerfen . Wenn Sie diese gewünschte Ausgabe wieder einzulesen würden Sie sich mit einem dict enden, die ein dict ({'boby': {'age': 34}}
, würden Sie nicht eine MyObj()
Instanz erhalten, weil es keine Tag-Informationen ist)
Die erweiterte Version für PyYAML, die ich entwickelt (ruamel.yaml) kann YAML mit Kommentaren lesen, Kommentare beibehalten und Kommentare beim Dumping schreiben. Wenn Sie Ihre gewünschte Ausgabe lesen, sehen die resultierenden Daten aus wie ein Diktat, das ein Diktat enthält (und handelt), aber in Wirklichkeit gibt es eine komplexere Datenstruktur, die mit den Kommentaren umgehen kann. Sie können diese Struktur jedoch erstellen, wenn Sie von ruamel.yaml aufgefordert werden, eine Instanz von MyObj
auszugeben. Wenn Sie die Kommentare zu diesem Zeitpunkt hinzufügen, erhalten Sie die gewünschte Ausgabe.
from __future__ import print_function
import sys
import ruamel.yaml
from ruamel.yaml.comments import CommentedMap
class MyObj():
name = "boby"
age = 34
def convert_to_yaml_struct(self):
x = CommentedMap()
a = CommentedMap()
x[data.name] = a
x.yaml_add_eol_comment('this is the name', 'boby', 11)
a['age'] = data.age
a.yaml_add_eol_comment('in years', 'age', 11)
return x
@staticmethod
def yaml_representer(dumper, data, flow_style=False):
assert isinstance(dumper, ruamel.yaml.RoundTripDumper)
return dumper.represent_dict(data.convert_to_yaml_struct())
ruamel.yaml.RoundTripDumper.add_representer(MyObj, MyObj.yaml_representer)
ruamel.yaml.round_trip_dump(MyObj(), sys.stdout)
Welche druckt:
boby: # this is the name
age: 34 # in years
Es gibt keine Notwendigkeit, mit der Erstellung der CommentedMap
Instanzen zu warten, bis Sie die MyObj
Instanz darstellen wollen. Ich würde z.B. Machen Sie name
und age
in Eigenschaften, die Werte von/auf dem geeigneten CommentedMap
erhalten/setzen. Auf diese Weise können Sie die Kommentare einfacher hinzufügen, bevor die statische Methode yaml_representer
aufgerufen wird, um die MyObj
Instanz darzustellen.
Ich bin mir fast sicher, dass es keine Möglichkeit gibt, dies mit PyYAML zu tun, ohne wesentliche Teile der Bibliothek neu zu schreiben und eine Reihe von Entscheidungen darüber zu treffen, wie man mit Kommentaren umgehen soll. Möchten Sie Kommentare vom Repräsentanten hinzugefügt werden (zB pro Klasse)? Oder per-instance irgendwie (noch härter)? Dies ist etwas bedauerlich, da die Möglichkeit, Kommentare hinzuzufügen, etwas nützlich sein könnte. – cge
Danke @cge. Das Einbehalten von Kommentaren wäre sehr hilfreich, wenn yaml-Dokumente programmatisch verarbeitet werden. –
http://www.dzone.com/snippets/pyyaml-comment-emitter scheint zu verstehen, wie man es mit den Event/Dumper-Schnittstellen macht. Ich habe noch keine Antwort gepostet, weil ich noch nicht bestätigt habe, dass es funktioniert. – kampu