2011-08-31 13 views
29

Ho un file YAML che assomiglia a questo:Salva/scaricare un file YAML con i commenti in PyYAML

# The following key opens a door 
key: value 

C'è un modo posso load e dump questi dati, pur mantenendo il commento?

+1

Una volta ho modificato il codice C libyaml per emettere commenti per mio uso personale. Estendere questo a PyYAML non sarà facile. –

risposta

11

PyYAML getta via i commenti a un livello molto basso (in Scanner.scan_to_next_token).

Mentre è possibile adattarlo o estenderlo per gestire i commenti in tutto lo stack, questa sarebbe una modifica importante. I commenti di Dump (= emittente) sembrano essere più semplici ed è stato discusso in ticket 114 sul vecchio bug tracker PyYAML. Purtroppo i vecchi biglietti non sono stati archiviati (e archive.org search è attualmente rotto).

+1

Hai ragione è stata una modifica importante, anche se più facile perché ho abbandonato il supporto <2.6 e ricombinato le fonti Py2 e Py3. – Anthon

38

Se si utilizza blocco strutturato YAML, è possibile utilizzare il pitone package¹ ruamel.yaml che è un derivato di PyYAML e supporta la conservazione di andata e ritorno di commenti:

import sys 
import ruamel.yaml 

yaml_str = """\ 
# example 
name: 
    # details 
    family: Smith # very common 
    given: Alice # one of the siblings 
""" 

code = ruamel.yaml.round_trip_load(yaml_str) 
code['name']['given'] = 'Bob' 

ruamel.yaml.round_trip_dump(code, sys.stdout) 

con esito:

# example 
name: 
    # details 
    family: Smith # very common 
    given: Bob  # one of the siblings 

Si noti che i commenti di fine riga sono ancora allineati.

Invece dei normali oggetti list e dict lo code è costituito da versioni avvolte² su cui sono associati i commenti.

¹ Installare con pip install ruamel.yaml. Funziona su Python 2.6/2.7/3.3 +
² ordereddict viene utilizzato in caso di una mappatura, per preservare l'ordinazione

+2

Questa dovrebbe essere la risposta accettata. – bram

+0

Questo non risponde alla domanda dell'OP. Conserva l'ordine, ma non i commenti. – Cerin

+2

@cerin Quali commenti mancano quando si esegue il codice sopra? Con quale versione di Python, ruamel.yaml e su quale piattaforma hai eseguito questo codice? Ho appena ripreso questo con l'ultima versione di ruamel.yaml (nel caso in cui ho rotto qualcosa) e l'output include ancora commenti. Data la quantità di upvotes qui, penso che altri siano stati in grado di ottenere lo stesso risultato e che potreste aver trascurato qualcosa. – Anthon

0

Ho un ramo di pyyaml ​​che fa esattamente questo. https://github.com/pflarr/pyyaml

Per creare un file yaml con commenti, è necessario creare un flusso di eventi che includa eventi di commento. Al momento, i commenti sono consentiti solo prima di elementi sequenza e chiavi di mappatura.

Questo funziona attualmente solo per python3, non l'ho portato alla versione python2 della libreria, ma potrebbe facilmente farlo su richiesta. Inoltre, questo dovrebbe anche essere abbastanza facile da portare in C libyaml, dato che il codice python è comunque una semplice porta.