2008-10-14 8 views
7

Estoy programando un sitio web en el que los usuarios tendrán una serie de configuraciones, como su elección de combinación de colores, etc. Me complace almacenar estos archivos como texto sin formato, y la seguridad no es un problema.Almacene la configuración de usuario simple en Python

La forma en que actualmente lo veo es: hay un diccionario, donde todas las claves son usuarios y los valores son diccionarios con la configuración de los usuarios en ellos.

Por ejemplo, userdb ["bob"] ["colour_scheme"] tendría el valor "azul".

¿Cuál es la mejor manera de almacenarlo en un archivo? ¿Decapando el diccionario?

¿Hay formas mejores de hacer lo que estoy tratando de hacer?

Respuesta

7

Usar el cPickle en el diccionario sería mi elección. Los diccionarios son una opción natural para este tipo de datos, por lo que, dados sus requisitos, no veo ninguna razón para no utilizarlos. Eso, a menos que estés pensando en leerlos de aplicaciones que no son de Python, en cuyo caso tendrías que usar un formato de texto neutral. E incluso aquí podría salirse con la escabeche más una herramienta de exportación.

+1

El problema con cPickle en este caso es que no se puede cargar la configuración para un solo usuario, tiene que cargarlo todo. deje de escalar mejor y es igualmente fácil de usar. –

+1

Si su diccionario incluye sus propios objetos (no solo los builtins), entonces puede tener problemas. En una futura revisión de su código, puede cambiar los nombres de las clases o mover las clases a otros paquetes. Entonces los datos viejos no se rehidratarán al nuevo código. – ChrisCantrell

0

Si tiene una base de datos, podría sugerir que guarde las configuraciones en la base de datos. Sin embargo, parece que los archivos comunes se adaptan mejor a su entorno.

Probablemente no desee almacenar todos la configuración de los usuarios en el mismo archivo, ya que podría tener problemas con el acceso simultáneo a ese archivo. Si almacenó las configuraciones de cada usuario como un diccionario en su propio archivo encurtido, entonces podrían actuar de manera independiente.

Decapado es una forma razonable de almacenar estos datos, pero desafortunadamente el formato de datos de pickle es notoriamente no legible por humanos. Es mejor que lo guarde como repr(dictionary), que será un formato más legible. Para volver a cargar la configuración del usuario, use eval(open("file").read()) o algo así.

6

No abordo la pregunta cuál es la mejor. Si desea manejar archivos de texto, consideraría ConfigParser -module. Otro que podría intentar sería simplejson o yaml. También podría considerar una tabla db real.

Por ejemplo, usted podría tener una tabla llamada userattrs, con tres columnas:

  • Int USER_ID
  • cadena nombre_atributo
  • cadena valor_atributo

Si hay muy pocos, usted podría almacénelos en cookies para una recuperación rápida.

4

Aquí está la manera más simple. Use variables simples y import el archivo de configuración.

llamar al archivo userprefs.py

# a user prefs file 
color = 0x010203 
font = "times new roman" 
position = (12, 13) 
size = (640, 480) 

En su aplicación, tiene que estar seguro de que se puede importar este archivo. Usted tiene muchas opciones de.

  1. Usando PYTHONPATH. Requiere PYTHONPATH configurar para incluir el directorio con los archivos de preferencias.

    a. Un parámetro de línea de comando explícito para nombrar el archivo (no el mejor, pero simple)

    b. Una variable de entorno para nombrar el archivo.

  2. Extendiendo sys.path para incluir el directorio personal del usuario

Ejemplo

import sys 
import os 
sys.path.insert(0,os.path.expanduser("~")) 
import userprefs 
print userprefs.color 
+0

¿No necesitarías entonces tener un archivo separado para cada usuario? Eso parece mucho sobrecargado. –

+0

@Mark Biek: "Estos usuarios tendrán una serie de configuraciones," Suena como una configuración por usuario para mí. Posiblemente malinterpretando la pregunta. –

+0

Lo voté porque es una gran solución para mi problema, que no es exactamente el que la pregunta plantea. Quiero un archivo de configuración para una aplicación de línea de comandos, que es un caso de uso bastante diferente. –

1

Si mejor legibilidad humana de configFiles importa una alternativa podría ser the ConfigParser module que le permite leer y escribir .ini como archivos . Pero luego estás restringido a un nivel de anidación.

2

Usaría shelve o una base de datos sqlite si tuviera que almacenar estas configuraciones en el sistema de archivos. Aunque, como está construyendo un sitio web, probablemente utilice algún tipo de base de datos, entonces ¿por qué no usarlo?

0

¿Hay alguna razón particular por la que no esté utilizando la base de datos para esto? parece lo normal y natural de hacer, o almacenar una configuración en blanco en el db en el ID de usuario o algo así.

No ha descrito los patrones de uso del sitio web, sino simplemente pensar en un sitio web general, pero creo que mantener la configuración en una base de datos provocaría menos E/S en disco que utilizando archivos.

OTOH, para las configuraciones que podrían usarse con el código del lado del cliente, almacenarlas como javascript en un archivo estático que se puede almacenar en caché sería útil, a expensas de tener varios lugares donde podría tener configuraciones. (Probablemente almacenaría esas configuraciones en el archivo db y reconstruiría los archivos estáticos según sea necesario)

0

Acepto la respuesta sobre el uso de Pickled Dictionary. Muy simple y eficaz para almacenar datos simples en una estructura de diccionario.

0

Si no le importa que pueda editar el archivo usted mismo, y desea una forma rápida de conservar los objetos Python, vaya con pickle. Si desea que el archivo sea legible por un humano, o puede ser leído por alguna otra aplicación, use ConfigParser. Si necesita algo más complejo, vaya con algún tipo de base de datos, ya sea relacional (sqlite) u orientado a objetos (axiom, zodb).

3

Para un sitio web basado en bases de datos, por supuesto, su mejor opción es una tabla db. Supongo que no estás haciendo lo de la base de datos.

Si no te importan los formatos legibles para los humanos, entonces pickle es una manera simple y directa de hacerlo. También he escuchado buenos informes sobre simplejson.

Si la legibilidad humana es importante, hay dos opciones simples presentan:

Módulo: sólo tiene que utilizar un módulo. Si todo lo que necesitas son unos pocos globales y nada lujoso, entonces este es el camino a seguir. Si realmente está desesperado, podría definir clases y variables de clase para emular secciones.La desventaja aquí: si el archivo será editado a mano por un usuario, los errores podrían ser difíciles de detectar y depurar.

Formato INI: He estado usando ConfigObj para esto, con bastante éxito. ConfigObj es esencialmente un reemplazo para ConfigParser, con soporte para secciones anidadas y mucho más. Opcionalmente, puede definir tipos o valores esperados para un archivo y validarlo, proporcionando una red de seguridad (y comentarios de error importantes) para usuarios/administradores.

9

me gustaría utilizar el módulo ConfigParser, que produce una cierta salida bastante legible y editable por el usuario para su ejemplo:

[bob] 
colour_scheme: blue 
british: yes 
[joe] 
color_scheme: that's 'color', silly! 
british: no

El siguiente código produciría el archivo de configuración arriba y, a continuación, imprimirlo:

import sys 
from ConfigParser import * 

c = ConfigParser() 

c.add_section("bob") 
c.set("bob", "colour_scheme", "blue") 
c.set("bob", "british", str(True)) 

c.add_section("joe") 
c.set("joe", "color_scheme", "that's 'color', silly!") 
c.set("joe", "british", str(False)) 

c.write(sys.stdout) # this outputs the configuration to stdout 
        # you could put a file-handle here instead 

for section in c.sections(): # this is how you read the options back in 
    print section 
    for option in c.options(section): 
      print "\t", option, "=", c.get(section, option) 

print c.get("bob", "british") # To access the "british" attribute for bob directly 

tenga en cuenta que sólo es compatible con ConfigParser cadenas, por lo que tendrá que convertir como lo he hecho anteriormente para los booleanos. Consulte effbot para obtener un buen resumen de los conceptos básicos.

1

El módulo sqlite3 incorporado probablemente sea mucho más simple que la mayoría de las alternativas, y lo prepara para actualizar a un RDBMS completo en caso de que lo desee o necesite.

Cuestiones relacionadas