2011-03-30 14 views

risposta

28

è possibile utilizzare un nodo ripetuto, in questo modo:

user_dir: &user_home /home/user 
user_pics: *user_home 

Non credo che è possibile concatenare però, quindi questo sarebbe non lavoro:

user_dir: &user_home /home/user 
user_pics: *user_home/pics 
+0

Grazie per averlo chiarito. Sciocco per aver pensato che fosse possibile. –

3

Mi sembra che lo stesso YAML does not define way to do this.

Le buone notizie sono che il consumatore YAML potrebbe essere in grado di capire le variabili.
Cosa userà il tuo YAML?

+0

Il mio file yaml funge da file di configurazione. Quello che ho incollato sopra era solo un esempio, per illustrare il problema. – Geo

+0

File di configurazione per cosa? –

+0

@ArnisL. [per esempio questo] (https://github.com/Hi-Angel/yi/blob/7dd59102a84dec6a1e52f4ddca49d5f259a76fdc/example-configs/yi-emacs-vty-static/stack.yaml) per definire un percorso per le directory del codice sorgente su costruire un modulo separato. –

3

userei un array, quindi unire la stringa insieme all'attuale simbolo del separatore del sistema operativo

come questo:

default: &default_path "you should not use paths in config" 
pictures: 
    - *default_path 
    - pics 
8

Se si utilizza Python con PyYaml, è possibile unire stringhe all'interno del file YAML. Purtroppo questa è solo una soluzione pitone, non universale uno:

con os.path.join:

user_dir: &home /home/user 
user_pics: !!python/object/apply:os.path.join [*home, pics] 

con string.join (per completezza - questo metodo ha la flessibilità essere utilizzato per molteplici forme di stringa giunzione:

user_dir: &home /home/user 
user_pics: !!python/object/apply:string.join [[*home, pics], /] 
+1

Sii chiaro su cosa significa questo approccio - stai permettendo al parser Pyyaml ​​di eseguire codice Python arbitrario dal file di input di yaml.Questo è un problema di sicurezza estremamente pericoloso se non si controlla la fonte dell'ingresso. Molti programmi useranno la funzione 'yaml.safe_load()' per evitare problemi di sicurezza. In tal caso, il tuo codice non funzionerà. –

+0

hai un esempio python3 per la connessione di stringhe? 'impossibile trovare il modulo 'str' (Nessun modulo chiamato 'str')' –

21

E 'sorprendente, dal momento che lo scopo della YAML ancoraggi & riferimenti è quello di fattore la duplicazione di file di dati YAML, che non ci sia un modo integrato per concatenare stringhe utilizzando referenc es. Il tuo caso d'uso di costruire un nome di percorso da parti è un buon esempio: ci devono essere molti di questi usi.

Fortunatamente esiste un modo semplice per aggiungere la concatenazione di stringhe a YAML tramite tag personalizzati in Python.

import yaml 

## define custom tag handler 
def join(loader, node): 
    seq = loader.construct_sequence(node) 
    return ''.join([str(i) for i in seq]) 

## register the tag handler 
yaml.add_constructor('!join', join) 

## using your sample data 
yaml.load(""" 
user_dir: &DIR /home/user 
user_pics: !join [*DIR, /pics] 
""") 

che si traduce in:

{'user_dir': '/home/user', 'user_pics': '/home/user/pics'} 

È possibile aggiungere altri elementi alla matrice, come " " o "-", se le stringhe devono essere delimitate.

+0

Grazie, questo funziona per me! – Chris

+2

Err ... Quindi, che cosa ha a che fare con YAML, un linguaggio di markup indipendente da Python, Haskell o altro? –

+0

La specifica YAML dice: "La digitazione esplicita è indicata da un tag che utilizza il punto esclamativo ("! ") ... È possibile utilizzare anche tag locali specifici dell'applicazione." Ho fornito un'implementazione di un tipo esplicito che soddisfa le specifiche. L'implementazione deve essere in una lingua. Ho usato Python perché l'OP diceva di volere un approccio più "ASCIUTTO" per il suo YAML, e DRY è un termine usato più spesso dalle persone di Python. Lo stesso tag personalizzato potrebbe essere implementato in altre lingue. In altre parole, ciò che l'OP richiesto non è disponibile in vaniglia YAML, ma è disponibile tramite un meccanismo di estensione definito da YAML. –