2008-10-14 12 views
7

Programuję stronę internetową, na której użytkownicy będą mieli wiele ustawień, takich jak wybór schematu kolorów itp. Z przyjemnością przechowuję je jako zwykłe pliki tekstowe, a zabezpieczenia nie są problem.Przechowywanie prostych ustawień użytkownika w Pythonie

Sposób, w jaki obecnie go widzę: jest słownik, w którym wszystkie klucze są użytkownikami, a wartości są słownikami z ustawieniami użytkowników w nich.

Na przykład userdb ["bob"] ["colour_scheme"] ma wartość "niebieski".

Jaki jest najlepszy sposób przechowywania pliku? Trawienie słownika?

Czy istnieją lepsze sposoby robienia tego, co próbuję zrobić?

Odpowiedz

7

Używanie w słowniku będzie moim wyborem. Słowniki są naturalne dla tego rodzaju danych, więc biorąc pod uwagę twoje wymagania, nie widzę powodu, aby ich nie używać. To, o ile nie myślisz o czytaniu ich z aplikacji innych niż python, w takim przypadku musisz użyć formatu tekstu neutralnego językowo. I nawet tutaj można uciec z marynatą i narzędziem eksportu.

+1

Problem z cPickle w tym przypadku polega na tym, że nie można załadować ustawień tylko dla jednego użytkownika, trzeba go załadować wszystkie. półka lepiej się skaluje i jest równie prosta w użyciu. –

+1

Jeśli twój słownik zawiera twoje własne obiekty (nie tylko wbudowane), możesz wpaść w kłopoty. W przyszłej wersji twojego kodu możesz zmienić nazwy klas lub przenieść klasy do innych pakietów. Następnie stare dane nie zostaną ponownie wprowadzone do nowego kodu. – ChrisCantrell

0

Jeśli masz bazę danych, mogę zasugerować przechowywanie ustawień w bazie danych. Jednak wygląda na to, że zwykłe pliki mogą lepiej pasować do twojego środowiska.

Prawdopodobnie nie chcesz przechowywać wszystkich ustawień użytkowników w tym samym pliku, ponieważ możesz napotkać problemy z równoczesnym dostępem do tego jednego pliku. Jeśli zapisałeś ustawienia każdego użytkownika jako słownik w ich własnym piklowanym pliku, wówczas byliby w stanie działać niezależnie.

Marynowanie jest rozsądnym sposobem przechowywania takich danych, ale niestety format danych pikle jest notorycznie nieczytelny dla człowieka. Być może lepiej będzie zapisać go jako repr(dictionary), który będzie bardziej czytelny. Aby ponownie załadować ustawienia użytkownika, użyj eval(open("file").read()) lub coś w tym stylu.

6

Nie zajmuję się pytaniem, który z nich jest najlepszy. Jeśli chcesz obsługiwać pliki tekstowe, rozważyłbym ConfigParser -module. Innym, co możesz spróbować, byłoby simplejson lub yaml. Można również wziąć pod uwagę prawdziwą tabelę db.

Na przykład można mieć tabeli o nazwie userattrs, z trzema kolumnami:

  • Int USER_ID
  • attribute_name String
  • String ATTRIBUTE_VALUE

Jeśli istnieje tylko kilka, można przechowywać je w ciasteczkach w celu szybkiego pobrania.

4

Oto najprostszy sposób. Użyj prostych zmiennych i import plik ustawień.

Wywołać plik userprefs.py

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

W aplikacji, trzeba mieć pewność, że można importować ten plik. Masz wiele opcji.

  1. Korzystanie z PYTHONPATH. Wymagaj ustawienia PYTHONPATH, aby zawrzeć katalog z plikami preferencji.

    a. Wyraźny parametr linii poleceń służący do nadania nazwy plikowi (nie najlepszym, ale prostemu): b. Zmienna środowiskowa do nazwania pliku.

  2. Rozszerzanie sys.path zawierać katalog domowy użytkownika

Przykład

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

Czy nie musiałbyś mieć osobnego pliku dla każdego użytkownika? Wydaje się, że dużo jest na głowie. –

+0

@Mark Biek: "Ci użytkownicy będą mieli wiele ustawień" To brzmi dla mnie jak ustawienia dla poszczególnych użytkowników. Prawdopodobnie błędne odczytanie pytania. –

+0

Głosowałem za tym, ponieważ jest to świetne rozwiązanie dla mojego problemu - który nie jest dokładnie tym, o co pyta. Chcę plik konfiguracyjny dla aplikacji wiersza poleceń, który jest dość inny przypadek użycia. –

1

Jeśli ludzki readablity z configfiles liczy alternatywą może być the ConfigParser module który pozwala na odczyt i zapis .ini jak pliki . Ale wtedy jesteś ograniczony do jednego poziomu zagnieżdżenia.

2

Chciałbym użyć shelve lub bazy danych sqlite, jeśli będę musiał zapisać te ustawienia w systemie plików. Chociaż, od kiedy budujesz stronę internetową, prawdopodobnie używasz jakiejś bazy danych, więc dlaczego po prostu tego nie użyć?

0

Czy istnieje szczególny powód, dla którego nie korzystasz z bazy danych? wydaje się normalną i naturalną rzeczą - lub przechowywać garść ustawień w db kluczem na identyfikator użytkownika lub coś podobnego.

Nie opisałeś wzorców korzystania ze strony internetowej, ale po prostu myślisz o ogólnej stronie internetowej - ale wydaje mi się, że zachowanie ustawień w bazie danych spowodowałoby znacznie mniej operacji wejścia/wyjścia dysku niż użycie plików.

OTOH, dla ustawień, które mogą być używane przez kod po stronie klienta, przechowywanie ich jako javascript w pliku statycznym, który może być buforowany, byłoby wygodne - kosztem posiadania wielu miejsc, w których możesz mieć ustawienia. (Prawdopodobnie zachowam te ustawienia w bazie danych iw razie potrzeby przebuduję pliki statyczne)

0

Zgadzam się z odpowiedzią na temat używania słownika marynowanego. Bardzo proste i skuteczne przechowywanie prostych danych w strukturze słownika.

0

Jeśli nie zależy Ci na możliwości samodzielnego edytowania pliku i chcesz szybko wypróbować obiekty Pythona, przejdź pod numer pickle. Jeśli chcesz, aby plik był czytelny dla człowieka lub możliwy do odczytania przez inną aplikację, użyj ConfigParser. Jeśli potrzebujesz czegoś bardziej złożonego, przejdź do jakiejś bazy danych, czy to relacyjnej (sqlite), czy zorientowanej obiektowo (axiom, zodb).

3

Dla witryny opartej na bazie danych oczywiście najlepszą opcją jest tabela db. Zakładam, że nie robisz bazy danych.

Jeśli nie interesują Cię formaty czytelne dla ludzi, to pickle to prosta i bezpośrednia droga. Słyszałem również dobre raporty na temat simplejson.

Jeśli ludzki czytelność jest ważna, dwie proste opcje prezentują się:

Moduł: Wystarczy użyć modułu. Jeśli potrzebujesz tylko kilku globali i nic nadzwyczajnego, to jest to droga. Jeśli naprawdę jesteś zdesperowany, możesz zdefiniować klasy i zmienne klasy, aby emulować sekcje.Wadą tutaj: jeśli plik zostanie ręcznie edytowany przez użytkownika, błędy mogą być trudne do uchwycenia i debugowania.

Format INI: Do tej pory używałem ConfigObj, z dużym sukcesem. ConfigObj jest w zasadzie zamiennikiem dla ConfigParser, z obsługą zagnieżdżonych sekcji i wiele więcej. Opcjonalnie można zdefiniować spodziewane typy lub wartości pliku i zatwierdzić je, zapewniając sieć bezpieczeństwa (i ważne informacje o błędach) dla użytkowników/administratorów.

9

chciałbym użyć modułu ConfigParser, która produkuje jedne wyjście dość czytelny i użytkownika można edytować za przykład:

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

Poniższy kod będzie produkować plik konfiguracyjny powyżej, a następnie wydrukować go:

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 

Należy zauważyć, że program ConfigParser obsługuje tylko łańcuchy, więc będziesz musiał konwertować tak jak powyżej dla Booleans. Zobacz effbot, aby uzyskać dobre omówienie podstaw.

1

Wbudowany moduł sqlite3 prawdopodobnie byłby znacznie prostszy niż większość alternatywnych rozwiązań i zapewnia gotowość do aktualizacji do pełnej wersji RDBMS w razie potrzeby lub potrzeby.

Powiązane problemy