¿Cuál es la mejor práctica usando un archivo de configuración en Python? [cerrado]

332

Tengo un script de línea de comandos que ejecuto con muchos argumentos. Ahora he llegado a un punto en el que tengo demasiados argumentos, y también quiero tener algunos argumentos en forma de diccionario.

Entonces, para simplificar las cosas, me gustaría ejecutar el script con un archivo de configuración. Realmente no sé qué bibliotecas usar para el análisis del archivo. ¿Cuál es la mejor práctica para hacer esto? Por supuesto, yo mismo podría resolver algo, pero si hay alguna biblioteca para esto, soy todo oídos.

Algunas 'demandas':

  • En lugar de usar, pickleme gustaría que fuera un archivo de texto sencillo que se pueda leer y editar fácilmente.
  • Quiero poder agregar datos similares a los de un diccionario, es decir, debería admitirse alguna forma de anidamiento.

Un pseudo archivo de ejemplo simplificado:

truck:
    color: blue
    brand: ford
city: new york
cabriolet:
    color: black
    engine:
        cylinders: 8
        placement: mid
    doors: 2
c00kiemonster
fuente
66
La sintaxis particular de este archivo de ejemplo es en realidad YAML, verifique la respuesta de Benson.
Skippy le Grand Gourou

Respuestas:

231

Puede tener un módulo Python normal, por ejemplo config.py, como este:

truck = dict(
    color = 'blue',
    brand = 'ford',
)
city = 'new york'
cabriolet = dict(
    color = 'black',
    engine = dict(
        cylinders = 8,
        placement = 'mid',
    ),
    doors = 2,
)

y úsalo así:

import config
print config.truck['color']  
dugres
fuente
69
Esta es una idea bastante mala, ya que si desea permitir que los usuarios con pocos privilegios puedan cambiar solo los archivos de configuración, de esta manera esencialmente les permite colarse en el código privilegiado.
nikolay
172
Permitir que los usuarios "con pocos privilegios" cambien la configuración de un programa más privilegiado es probablemente una configuración cuestionable de todos modos.
XTL
18
También puede tener problemas para empaquetar su proyecto para su implementación utilizando una herramienta como py2app. Es posible que el usuario no pueda editar el archivo de configuración una vez que se distribuye, ya que invalidaría la firma de la aplicación.
bschwagg
18
La principal desventaja de esto (de lo contrario, una opción muy conveniente) es que los .pyarchivos son ejecutables, por lo que se podría ejecutar cualquier tipo de código al intentar cargar la configuración import. Eso es inaceptable desde el punto de vista de la seguridad.
Apalala
55
¿No se puede hacer una versión de esto de forma segura ast.literal_eval? docs.python.org/3/library/ast.html#ast.literal_eval
André C. Andersen
169

La configuración de muestra que proporcionó es realmente válida YAML . De hecho, YAML cumple con todas sus demandas, se implementa en una gran cantidad de idiomas y es extremadamente amigable para los humanos. Le recomiendo que lo use. El proyecto PyYAML proporciona un buen módulo de Python que implementa YAML.

Usar el módulo yaml es extremadamente simple:

import yaml
config = yaml.safe_load(open("path/to/config.yml"))
Benson
fuente
3
yaml es siempre algo a lo que recurro; el formato puede ser desde simple hasta compatible con código de python incrustado, y la biblioteca estándar hace el trabajo pesado de análisis y saneamiento por usted.
Todor Minakov
15
Convenido. Para usted o los usuarios que escriben YAML, aquí está la mejor referencia de YAML que conozco . La documentación oficial es por desgracia una especificación dirigida a los ejecutores, y nada más, pero la guía de Eevee es fantástico.
Esteis
55
Para nosotros no iniciados, eso es pip3 install pyyamlpara que esté listo para importar en scripts de Python.
user8675309
2
Tenga cuidado, yaml solo es amigable si lo mantiene muy simple, por defecto tiene toneladas de problemas, bordeando características inseguras. Pruebe hitchdev.com/strictyaml en su lugar como una alternativa lite segura por defecto.
Gringo Suave
107

Encontré esto como el más útil y fácil de usar https://wiki.python.org/moin/ConfigParserExamples

Simplemente crea un "myfile.ini" como:

[SectionOne]
Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True

[SectionTwo]
FavoriteColor=Green
[SectionThree]
FamilyName: Johnson

[Others]
Route: 66

Y recuperar los datos como:

>>> import ConfigParser
>>> Config = ConfigParser.ConfigParser()
>>> Config
<ConfigParser.ConfigParser instance at 0x00BA9B20>
>>> Config.read("myfile.ini")
['c:\\tomorrow.ini']
>>> Config.sections()
['Others', 'SectionThree', 'SectionOne', 'SectionTwo']
>>> Config.options('SectionOne')
['Status', 'Name', 'Value', 'Age', 'Single']
>>> Config.get('SectionOne', 'Status')
'Single'
Maviles
fuente
20
Para Python 3 use el módulo configparser en su lugar (todo en minúsculas)
Roland
2
Esta es la solución más rápida, clara y fácil de implementar, ya que no hay implementación, solo uso. :) ¡Gracias!
Aleksandar
Sin embargo, ¿esto admitiría diccionarios anidados como se hizo en la pregunta?
Jakub Bláha
54

Yaml y Json son los formatos de archivo más simples y más utilizados para almacenar configuraciones / configuraciones. PyYaml se puede usar para analizar yaml. Json ya es parte de Python desde 2.5. Yaml es un superconjunto de Json. Json resolverá la mayoría de los casos de uso, excepto cadenas de líneas múltiples donde se requiere escapar. Yaml también se encarga de estos casos.

>>> import json
>>> config = {'handler' : 'adminhandler.py', 'timeoutsec' : 5 }
>>> json.dump(config, open('/tmp/config.json', 'w'))
>>> json.load(open('/tmp/config.json'))   
{u'handler': u'adminhandler.py', u'timeoutsec': 5}
Anoop
fuente
13
Si bien es más o menos equivalente, json no es tan legible para los humanos como yaml. Dado que su configuración de muestra es realmente válida yaml, enfatizaría eso en lugar de json.
Benson
23
El uso de "json.dump (config, fp, sort_keys = True, indent = 4)" mejora la legibilidad.
phobie 01 de