Probabilmente avete qualche representer per la classe MyObj, come di default dumping (print(yaml.dump(MyObj()))
) con PyYAML vi darà:
!!python/object:__main__.MyObj {}
PyYAML può fare solo una cosa con i commenti in l'output desiderato: disfarsene . Se volete leggere che l'output desiderato indietro, si finisce con un dict contenente un dict ({'boby': {'age': 34}}
, non si ottiene un'istanza MyObj()
perché non ci sono informazioni tag)
La versione avanzata per PyYAML che ho sviluppato (ruamel.yaml) può leggere in YAML con commenti, conservare i commenti e scrivere commenti durante il dumping. Se si legge l'output desiderato, i dati risultanti appariranno (e agiranno) come un dict contenente un dict, ma in realtà esiste una struttura dati più complessa in grado di gestire i commenti. Tuttavia è possibile creare tale struttura quando ruamel.yaml chiede di scaricare un'istanza di MyObj
e se si aggiungono i commenti in quel momento, si otterrà l'output desiderato.
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)
che stampa:
boby: # this is the name
age: 34 # in years
Non v'è alcuna necessità di attendere con la creazione delle CommentedMap
casi fino a quando si vuole rappresentare l'istanza MyObj
. Vorrei ad es. make name
e age
in proprietà che ottengono/impongono valori da/sull'appropriato CommentedMap
. In questo modo è possibile aggiungere più facilmente i commenti prima che il metodo statico yaml_representer
venga chiamato per rappresentare l'istanza MyObj
.
Sono quasi certo che non c'è modo di farlo con PyYAML, in pratica, essenzialmente per riscrivere le parti principali della libreria e prendere una serie di decisioni su come gestire i commenti. Volete i commenti aggiunti dal rappresentante (ad esempio, per classe)? O per esempio in qualche modo (anche più difficile)? Questo è un po 'sfortunato, in quanto la possibilità di aggiungere commenti potrebbe essere in qualche modo utile. – cge
Grazie a @cge. Conservare i commenti sarebbe molto utile quando si elaborano i documenti yaml in modo programmatico. –
http://www.dzone.com/snippets/pyyaml-comment-emitter sembra capire come farlo usando le interfacce Event/Dumper. Non pubblicare ancora una risposta perché non ho ancora verificato che funzioni. – kampu