2009-06-08 16 views
41

Django usa archivos de Python reales para la configuración, Trac usa un archivo .ini y algunas otras piezas de software usan archivos XML para contener esta información.¿Cuál es la forma oficial de almacenar la configuración de los programas de Python?

¿Son uno de estos enfoques bendecidos por Guido y/o por la comunidad de Python más que por otro?

+1

Según Wikipedia, los archivos "ini" fueron predominantes en las ventanas donde se ha dejado de utilizar. Entonces IMO, deberías saltarte esa opción. – WhyNotHugo

+0

De Microsoft: [¿Por qué los archivos INI están en desuso en favor del registro?] (Https://blogs.msdn.microsoft.com/oldnewthing/20071126-00/?p=24383) – jkdev

Respuesta

24

Depende de la audiencia prevista predominante.

Si se trata de programadores que cambian el archivo de todos modos, sólo tiene que utilizar archivos pitón como settings.py

Si se trata de los usuarios finales a continuación, piense en los archivos ini.

+19

¿Cómo se ve un archivo 'settings.py' típico? –

+2

Creo que se está refiriendo al archivo settings.py de Django. Es un archivo python válido con declaraciones de cadenas, tuplas, listas y otras variables. – pcx

+3

Estoy de acuerdo con la primera parte, pero si los usuarios finales necesitan modificarla, algo que ConfigParser puede leer. – WhyNotHugo

5

No estoy seguro de que exista una forma "oficial" (no se menciona en el Zen de Python :)) - Tiendo a utilizar el módulo Config Parser y creo que eso es muy común. Prefiero eso sobre el enfoque de archivo python porque puede escribir de nuevo y volver a cargar dinámicamente si lo desea.

1

¿por qué Guido bendijo algo que está fuera de su alcance? No, no hay nada particularmente bendecido.

+2

upvoted, porque en realidad respondió la pregunta de OPs ("No, no hay nada particularmente bendecido"). Los votos a favor podrían provenir de la primera parte de su respuesta: Tener una comunidad con las "mejores prácticas" puede ayudar a comenzar en un nuevo idioma/nuevo proyecto ... –

+0

Entiendo el papel de las decisiones de Guido en relación con el desarrollo básico, stdlib , etc., pero la pregunta es acerca del uso básico donde las buenas prácticas difícilmente pueden definirse. – SilentGhost

0

Es más de conveniencia. No hay forma oficial por decir. Pero usar archivos XML tendría sentido ya que pueden ser manipulados por varias otras aplicaciones/bibliotecas.

+4

lo mismo puede decirse acerca de archivos json, ini, etc. – SilentGhost

+9

Se supone que los humanos no deben leer/escribir en XML. –

+1

Leer XML con la biblioteca estándar de Python es simplemente un dolor ... –

2

Depende en gran medida de lo complicada que sea su configuración. Si está haciendo una asignación de clave-valor simple y desea la capacidad de editar la configuración con un editor de texto, creo que ConfigParser es el camino a seguir.

Si sus configuraciones son complicadas e incluyen listas y estructuras de datos anidadas, usaría XML o JSON y crearía un editor de configuración.

Para cosas realmente complicadas donde no se espera que el usuario final cambie mucho la configuración, o es más confiable, simplemente cree un conjunto de clases de Python y evalúe un script de Python para obtener la configuración.

9

No sé si esto se puede considerar "oficial", pero está en la biblioteca estándar: 14.2. ConfigParser — Configuration file parser.

Esto es, obviamente, no una solución universal, sin embargo. Solo use lo que le parezca más apropiado para la tarea, sin ninguna complejidad necesaria (y, especialmente, ¡completa, piense en los configuradores automáticos o GUI).

+1

json también está en la biblioteca estándar, junto con todo tipo de módulos de procesamiento xml – SilentGhost

+4

Sure JSON es estándar, pero este es el módulo que se denomina "Analizador de archivos de configuración" por algún motivo. Me parece genial para leer/escribir, y bastante fácil de entender para usuarios novatos y novatos. – WhyNotHugo

8

Solo una opción más, PyQt. Qt tiene una forma independiente de plataforma de almacenar configuraciones con la clase QSettings. Debajo del capó, en Windows usa el registro y en Linux almacena la configuración en un archivo conf confidente. QSettings funciona muy bien y es bastante parecido.

27

Como muchos han dicho, no hay una forma "oficial". Sin embargo, hay muchas opciones. Hubo a talk at PyCon este año sobre muchas de las opciones disponibles.

+4

@mac, lo encontré: http: // blip.tv/pycon-us-videos-2009-2010-2011/a-configuration-comparison-in-python-2006550 – utdemir

+0

@utdemir - Gracias, actualicé la respuesta original con su enlace, eliminando mi comentario original ... – mac

15

utilizo un estante (http://docs.python.org/library/shelve.html):

shelf = shelve.open(filename) 
shelf["users"] = ["David", "Abraham"] 
shelf.sync() # Save 
+1

De docs, "Debido a que el módulo shelve está respaldado por pickle, no es seguro cargar un estante de una fuente no confiable. Al igual que con pickle, cargar un estante puede ejecutar código arbitrario". Si esta pregunta está destinada a guiar a los principiantes, todos deberían señalarlos al módulo configparser, de lo contrario, a JSON o a un archivo personalizado. Las secciones del archivo INI son más definidas (legibles) que JSON, incluso si usted pretifica su código. [] Brackes agrega un poco de sentido de negrita, por lo que las secciones son fáciles de ver. – erm3nda

2

Para aplicaciones web me gusta usar variables de entorno de sistema operativo: os.environ.get('CONFIG_OPTION')

Esto funciona especialmente bien para los ajustes que varían entre despliega.Puede leer más acerca de la razón detrás de usar env vars aquí: http://www.12factor.net/config

Por supuesto, esto solo funciona para valores de solo lectura porque los cambios en el entorno generalmente no son persistentes. Pero si no necesitas acceso de escritura, son una muy buena solución.

+0

No está mal, pero tener muchos vars para configurarlo podría ser más conveniente hacerlo de la manera Django: almacénelo en un archivo y establezca diferentes archivos según una única variable de entorno (en django, DJANGO_SETTINGS_MODULE). De esta forma, también puede tener valores dinámicos y de escritura. – danigosa

+0

Si está utilizando este método, es posible que también desee echarle un vistazo a https://github.com/theskumar/python-dotenv – smilledge

3

No hay una solución bendecida hasta donde yo sé. No existe una forma correcta o incorrecta de almacenar la configuración de la aplicación, ni xml, json ni todos los tipos de archivos están bien, siempre y cuando te sientas cómodo. Para Python personalmente uso pypref es muy fácil, multiplataforma y directo.

pypref es muy útil, ya que uno puede almacenar configuraciones y preferencias estáticas y dinámicas ...

from pypref import Preferences 

    # create singleton preferences instance 
    pref = Preferences(filename="preferences_test.py") 

    # create preferences dict 
    pdict = {'preference 1': 1, 12345: 'I am a number'} 

    # set preferences. This would automatically create preferences_test.py 
    # in your home directory. Go and check it. 
    pref.set_preferences(pdict) 

    # lets update the preferences. This would automatically update 
    # preferences_test.py file, you can verify that. 
    pref.update_preferences({'preference 1': 2}) 

    # lets get some preferences. This would return the value of the preference if 
    # it is defined or default value if it is not. 
    print pref.get('preference 1') 

    # In some cases we must use raw strings. This is most likely needed when 
    # working with paths in a windows systems or when a preference includes 
    # especial characters. That's how to do it ... 
    pref.update_preferences({'my path': " r'C:\Users\Me\Desktop' "}) 

    # Sometimes preferences to change dynamically or to be evaluated real time. 
    # This also can be done by using dynamic property. In this example password 
    # generator preference is set using uuid module. dynamic dictionary 
    # must include all modules name that must be imported upon evaluating 
    # a dynamic preference 
    pre = {'password generator': "str(uuid.uuid1())"} 
    dyn = {'password generator': ['uuid',]} 
    pref.update_preferences(preferences=pre, dynamic=dyn) 

    # lets pull 'password generator' preferences twice and notice how 
    # passwords are different at every pull 
    print pref.get('password generator') 
    print pref.get('password generator') 

    # those preferences can be accessed later. Let's simulate that by creating 
    # another preferences instances which will automatically detect the 
    # existance of a preferences file and connect to it 
    newPref = Preferences(filename="preferences_test.py") 

    # let's print 'my path' preference 
    print newPref.get('my path') 
+0

'pypref' totalmente rock. Sorprendentemente simple y fácil de usar (me recuerda las "Preferencias Compartidas" de Android, tal vez por eso). Felicidades por el gran trabajo! – dentex

1

Una de las maneras más fáciles de lo que es el uso está utilizando el módulo json. Guarde el archivo en config.json con los detalles como se muestra a continuación.

Guardar datos en el archivo JSON:

{ 

    "john" : { 
     "number" : "948075049" , 
     "password":"thisisit" 
    }  
} 

al leer el archivo JSON:

import json 

#open the config.json file 

with open('config.json') as f: 
    mydata = json.load(f) ; 

#Now mydata is a python dictionary 

print("username is " , mydata.get('john').get('number') , " password is " , mydata.get('john').get('password')) ; 
+0

Tenga en cuenta que 'mydata.get ('john'). Get ('number')' no es un buen código. Si no hay una clave 'john' en los datos,' mydata.get ('john') 'devolverá' None', y '.get ('number')' generará una excepción. El uso de '.get' supone que desea manejar los datos faltantes correctamente; así que mejor haz esto: 'mydata.get ('john', {}). get ('number')' - esto no dará como resultado una excepción, a menos que 'mydata' no sea un' dict'. – MarSoft

Cuestiones relacionadas