2011-03-30 13 views

Respuesta

28

Usted puede utilizar un nodo repetido, como esto:

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

No creo que puede concatenar sin embargo, por lo que este no sería trabajo:

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

Gracias por aclarar eso. Tonto por pensar que esto era posible. –

3

Me parece que el propio YAML does not define way to do this.

Las buenas noticias son que el consumidor de YAML podría ser capaz de comprender las variables.
¿Qué utilizará su YAML?

+0

Mi archivo yaml sirve como un archivo de configuración. Lo que pegué arriba fue solo un ejemplo para ilustrar el problema. – Geo

+0

¿Archivo de configuración para qué? –

+0

@ArnisL. [por ejemplo, este] (https://github.com/Hi-Angel/yi/blob/7dd59102a84dec6a1e52f4ddca49d5f259a76fdc/example-configs/yi-emacs-vty-static/stack.yaml) para definir una ruta a los directorios de código fuente en construyendo un módulo separado. –

3

me gustaría utilizar una matriz, luego unir la cadena junto con el símbolo del separador del sistema operativo actual

como este:

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

Si está utilizando python con PyYaml, es posible unir cadenas en el archivo YAML. Por desgracia, esto es sólo una solución pitón, no es un universal de uno:

con os.path.join:

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

con string.join (por el bien completo - este método tiene la flexibilidad para ser usado para múltiples formas de cadena unirse:

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

Sea claro en lo que significa este enfoque: está permitiendo que el analizador Pyyaml ​​ejecute código Python arbitrario a partir del archivo de entrada yaml.Este es un problema de seguridad extremadamente peligroso si no controla la fuente de la entrada. Muchos programas usarán la función 'yaml.safe_load()' para evitar el problema de seguridad. En ese caso, su código no funcionará. –

+0

¿tiene un ejemplo de python3 para unir cadenas? 'no se puede encontrar el módulo 'str' (Ningún módulo llamado 'str')' –

21

es sorprendente, ya que el propósito de YAML ancla & referencias es factorizar la duplicación de archivos de datos YAML, que no hay una manera integrada para concatenar cadenas utilizando referenc es. Su caso de uso de compilar un nombre de ruta a partir de partes es un buen ejemplo; debe haber muchos usos.

Afortunadamente hay una manera simple de agregar la concatenación de cadenas a YAML a través de etiquetas personalizadas en 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] 
""") 

que se traduce en:

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

Puede añadir más elementos a la matriz, como " " o "-", si las cadenas deben estar delimitados.

+0

¡Gracias, esto funciona para mí! – Chris

+2

Err ... Entonces, ¿qué tiene que ver con YAML, un lenguaje de marcado independiente de Python, Haskell o lo que sea? –

+0

La especificación YAML dice: "El tipeo explícito se denota con una etiqueta usando el signo de exclamación ("! ") ... También se pueden usar etiquetas locales específicas de la aplicación." Proporcioné una implementación de un tipo explícito que cumple con las especificaciones. La implementación tiene que ser en algún idioma. Utilicé Python porque OP dijo que quería un enfoque más "SECO" para su YAML, y DRY es un término utilizado con mayor frecuencia por personas de Python. La misma etiqueta personalizada podría implementarse en otros idiomas. En otras palabras, lo que el OP solicitó no está disponible en vainilla YAML, pero está disponible a través de un mecanismo de extensión definido por YAML. –

Cuestiones relacionadas