Question

Je suis en train de programmer un site Web sur lequel les utilisateurs auront un certain nombre de paramètres, tels que leur choix de couleurs, etc. Je suis heureux de les stocker sous forme de fichiers texte, la sécurité n’est pas un problème.

Voici ce que je vois actuellement: il existe un dictionnaire où toutes les clés sont des utilisateurs et les valeurs sont des dictionnaires contenant les paramètres de l'utilisateur.

Par exemple, userdb ["bob"] ["colour_scheme"] aurait la valeur "bleu".

Quel est le meilleur moyen de le stocker dans un fichier? Choisir le dictionnaire?

Existe-t-il de meilleurs moyens de faire ce que j'essaie de faire?

Était-ce utile?

La solution

Utiliser cPickle dans le dictionnaire serait mon choix. Les dictionnaires conviennent parfaitement à ce type de données. Par conséquent, vu vos besoins, je ne vois aucune raison de ne pas les utiliser. Cela, sauf si vous envisagez de les lire à partir d'applications autres que Python, auquel cas vous devrez utiliser un format de texte neutre. Et même ici, vous pouvez vous en sortir avec le cornichon et un outil d’exportation.

Autres conseils

J'utiliserais le module ConfigParser , qui produit une sortie assez lisible et modifiable par l'utilisateur pour votre exemple:

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

Le code suivant produira le fichier de configuration ci-dessus, puis l’imprimera:

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

Notez que ConfigParser ne prend en charge que les chaînes. Vous devrez donc convertir comme indiqué ci-dessus pour les booléens. Voir effbot pour une bonne description des bases.

Je n’aborde pas la question de savoir lequel est le meilleur. Si vous souhaitez gérer les fichiers texte, je considérerais ConfigParser - module . Vous pouvez également essayer simplejson ou yaml . Vous pouvez également envisager une vraie table de base de données.

Par exemple, vous pourriez avoir une table appelée userattrs, avec trois colonnes:

  • Int user_id
  • Chaîne nom_attribut
  • String attribut_value

S'il n'y en a que quelques-uns, vous pouvez les stocker dans des cookies pour les récupérer rapidement.

Voici le moyen le plus simple. Utilisez des variables simples et importez le fichier de paramètres.

Appelez le fichier userprefs.py

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

Dans votre application, vous devez être sûr de pouvoir importer ce fichier. Vous avez beaucoup de choix.

  1. Utilisation de PYTHONPATH . Exiger que PYTHONPATH soit défini pour inclure le répertoire avec les fichiers de préférences.

    a. Un paramètre de ligne de commande explicite pour nommer le fichier (pas le meilleur, mais le plus simple)

    b. Une variable d'environnement pour nommer le fichier.

  2. Extension de sys.path pour inclure le répertoire de base de l'utilisateur

Exemple

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

Pour un site Web basé sur une base de données, bien sûr, votre meilleure option est une table de base de données. Je suppose que vous ne faites pas la chose de la base de données.

Si vous ne vous souciez pas des formats lisibles par l'homme, alors pickle est une solution simple et directe. J'ai également entendu de bons rapports sur simplejson .

Si la lisibilité humaine est importante, deux options simples se présentent:

Module: utilisez simplement un module. Si vous n'avez besoin que de quelques globals et de rien d’exceptionnel, c’est la voie à suivre. Si vous êtes vraiment désespéré, vous pouvez définir des classes et des variables de classe pour émuler des sections. Inconvénient: si le fichier est édité à la main par un utilisateur, les erreurs risquent d’être difficiles à détecter et à déboguer.

Format INI: j'utilise ConfigObj Pour cela, avec pas mal de succès. ConfigObj est essentiellement un remplacement de ConfigParser, avec une prise en charge des sections imbriquées et bien plus encore. Vous pouvez éventuellement définir les types ou les valeurs attendus pour un fichier et le valider, fournissant ainsi un filet de sécurité (et un retour d'erreur important) aux utilisateurs / administrateurs.

Je voudrais utiliser shelve ou un < une href = "http://www.python.org/doc/2.5.2/lib/module-sqlite3.html" rel = "nofollow noreferrer"> base de données sqlite si je dois stocker ces paramètres sur le système de fichiers. Cependant, puisque vous construisez un site Web, vous utilisez probablement une sorte de base de données, alors pourquoi ne pas simplement l'utiliser?

Le module sqlite3 intégré être probablement beaucoup plus simple que la plupart des alternatives, et vous prépare à la mise à jour vers un SGBDR complet si vous le souhaitez ou en avez besoin.

Si la disponibilité humaine des fichiers de configuration est importante, une alternative peut être le module ConfigParser qui vous permet de lire et d’écrire des fichiers .ini. Mais alors vous êtes limité à un seul niveau de nidification.

Si vous avez une base de données, je pourrais suggérer de stocker les paramètres dans la base de données. Cependant, il semble que les fichiers ordinaires conviennent mieux à votre environnement.

Vous ne souhaitez probablement pas stocker tous les paramètres des utilisateurs dans le même fichier, car vous pourriez rencontrer des problèmes avec l'accès simultané à ce fichier. Si vous stockiez les paramètres de chaque utilisateur sous forme de dictionnaire dans son propre fichier mariné, ils seraient alors en mesure d’agir indépendamment.

Le pickling est un moyen raisonnable de stocker de telles données, mais malheureusement, le format de ces données est notoirement illisible. Vous feriez mieux de le stocker sous repr (dictionnaire) qui sera un format plus lisible. Pour recharger les paramètres utilisateur, utilisez eval (open ("fichier"). Read ()) ou quelque chose du genre.

Y a-t-il une raison particulière pour laquelle vous n'utilisez pas la base de données à cette fin? cela semble être la chose normale et naturelle à faire - ou stocker un compte-gouttes des paramètres dans la base de données en fonction de l'ID utilisateur ou quelque chose du genre.

Vous n'avez pas décrit les modèles d'utilisation du site Web, mais pensez à un site Web général - mais je penserais que le fait de conserver les paramètres dans une base de données causerait beaucoup moins d'entrées / sorties de disque que d'utiliser des fichiers.

OTOH, pour les paramètres pouvant être utilisés par le code côté client, les stocker au format javascript dans un fichier statique pouvant être mis en cache serait pratique - au lieu d'avoir plusieurs emplacements, vous pourriez avoir des paramètres. (Je stockerais probablement ces paramètres dans la base de données et recréerais les fichiers statiques si nécessaire)

Je suis d’accord avec la réponse concernant l’utilisation du dictionnaire pickled. Très simple et efficace pour stocker des données simples dans une structure de dictionnaire.

Si vous ne souhaitez pas modifier le fichier vous-même et que vous souhaitez conserver rapidement les objets Python persistants, utilisez pickle . Si vous souhaitez que le fichier soit lisible par un humain ou par une autre application, utilisez ConfigParser . Si vous avez besoin de quelque chose de plus complexe, choisissez une sorte de base de données, qu'elle soit relationnelle ( sqlite ) ou orienté objet ( axiome , zodb ).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top