Archivos YAML
YAML
YAML (YAML Ain't Markup Language™) es un formato de archivo muy popular para archivos de configuraciones y también se usa para intercambio de datos. Es un formato simple de leer aunque también es muy sensible respecto al indentado.
Este formato no está implementado de forma nativa en Python, por ello se requiere recurrir a paquetes externos. En esta página se propone PyYAML.
Formato
Los archivos YAML permiten guardar tanto listas como diccionarios. A continuación se muestran algunos ejemplos.
Listas
Listas de diccionarios
Diccionarios
Nótese que el valor true
se convierte a booleano True
automáticamente.
Multiples objetos
Un mismo archivo puede guardar varios objetos de datos:
# objeto Nº1
data_numerica:
- x : 4
- y : 9
- z : -1
--- # separador de objetos
# objeto Nº2
debug: true
Comentarios
YAML soporta comentarios internos,
los cuales son precedidos por un numeral (#
)
al comienzo del renglón.
Esta es una ventaja frente al formato JSON,
el cual no acepta comentarios internos.
PyYAML
PyYAML es el paquete más usado para dar soporte en Python.
Instalacion
El paquete es instalable desde PIP:
Importacion
El módulo debe importarse para su uso.
Lectura desde archivo
Para leer los archivos hay dos funciones específicas llamadas safe_load()
y safe_load_all()
.
Objeto único
Para leer y decodificar archivos con un único objeto de datos se recomienda usar la función safe_load()
:
ruta = "data_simple.yml"
with open(ruta, 'r') as archivo:
data_archivo = yaml.safe_load(archivo)
print(data_archivo)
print(type(data_archivo)) # 'dict'
Lectura insegura
La función load()
permite la ejecución de código malicioso guardado y por ello está marcada como obsoleta.
safe_load()
es su versión recortada,
que tiene menos opciones pero que es mucho más segura de usar.
Data única
safe_load()
no admite archivos con data múltiple, porque de intentarse el intérprete dará error e interrumpirá el programa.
Objetos múltiples
En caso deque el archivo contenga múltiples objetos de datos se usa la función safe_load_all()
.
datos = []
ruta = "data_doble.yml"
with open(ruta, 'r') as archivo:
data_archivo = yaml.safe_load_all(archivo) # tipo salida 'generator'
# la data debe extraerse antes de cerrar el archivo
for data in data_archivo:
datos.append(data)
print(datos)
generator
el cual debe recorrerse para rescatar la información antes de cerrar el archivo
Conversion desde strings
Las funciones safe_load()
y safe_load_all()
admiten a su entrada datos en formato texto simple.
Objeto único
nombres_texto = """
data_numerica:
- x : 4
- y : 9
- z : -1
"""
data_nombres = yaml.safe_load(nombres_texto) # diccionario
Objetos múltiples
datos_texto = """
# objeto Nº1
data_numerica:
- x : 4
- y : 9
- z : -1
---
# objeto Nº2
debug: true
"""
data_nombres = []
generador_data = yaml.safe_load_all(datos_texto)
for data in generador_data:
data_nombres.append(data)
print(data_nombres)
Indentado
Hay que evitar a toda costa el tabular la secuencia ---
para evitar errores de lectura.
Guardado de datos
Para el guardado de objetos en archivos YAML se usa la función dump()
:
data_nombres: dict|list
ruta_salida = "data_salida.yml"
with open(ruta_salida, 'w') as archivo:
yaml.dump(data_nombres, archivo)
Otras opciones:
Referencias
Python Land - Python YAML: How to Load, Read, and Write YAML