2009-05-05 26 views
12

Así que estoy jugando con la idea de hacer de mí (y de cualquiera que quiera usarlo por supuesto) una pequeña biblioteca repetitiva en Python para Pygame. Me gustaría un sistema donde la configuración de la aplicación se proporciona con un archivo yaml.Yaml merge en Python

Así que estaba pensando que sería útil si la biblioteca proporcionara un árbol yaml predeterminado y lo fusionara con uno proporcionado por el usuario. Por motivos de usabilidad me pregunto si es posible que haya alguien que adivine una rutina donde:

En cualquier caso, en el árbol donde el usuario suministró yaml se superpone al predeterminado, las ramas suministradas por el usuario reemplazan a las que se suministran.

En cualquier caso donde el usuario suministró yaml no se superpone al árbol predeterminado, el árbol predeterminado persiste.

Se añaden todas las ramas superfloras en el árbol proporcionadas por el yaml proporcionado por el usuario.

Sé que esta explicación fue prolija, ya que es probable que esté claro lo que estoy pidiendo. Me pregunto si es mucho obtener gratis.

+0

¿Cómo debería manejar tipos conflictivos, como una lista en el árbol predeterminado, y un diccionario en el árbol de configuración? ¿Debería fusionar listas, y en ese caso, cómo? –

Respuesta

21

usted podría utilizar PyYAML para analizar los archivos, y luego la siguiente función para fusionar dos árboles:

def merge(user, default): 
    if isinstance(user,dict) and isinstance(default,dict): 
     for k,v in default.iteritems(): 
      if k not in user: 
       user[k] = v 
      else: 
       user[k] = merge(user[k],v) 
    return user 

Opcionalmente, se puede hacer un deep-copy de la facilidad de uso del árbol antes de llamar a esta función.

+0

¿Por qué no user.update (predeterminado)? –

+0

Es default.update (usuario), ya que dict.update sobrescribe las claves existentes. Para saber dónde recurrir más profundamente en el árbol, tendría que iterar sobre el diccionario unido, que es más grande o igual al más grande del usuario y por defecto. –

+2

muy agradable, gracias! Aunque imho pierde la fusión entre matrices: si una clave tiene [1,2] y la otra clave tiene [2,3], el elemento fusionado debería tener [1,2,3]. ¿Me equivoco? – Riccardo