Я программирую веб-сайт, на котором у пользователей будет ряд настроек, таких как выбор цветовой схемы и т. д. Я счастлив хранить их в виде текстовых файлов, и безопасность не является проблемой.
В настоящее время я вижу это так: есть словарь, где все ключи - это пользователи, а значения - это словари с пользовательскими настройками в них.
Например, userdb ["bob"] ["colour_scheme"] будет иметь значение "blue".
Как лучше всего хранить его в файле? Травление словаря?
Есть ли лучшие способы делать то, что я пытаюсь сделать?






Я бы предпочел использовать cPickle в словаре. Словари естественным образом подходят для такого рода данных, поэтому, учитывая ваши требования, я не вижу причин не использовать их. Это, если вы не думаете о чтении их из приложений, отличных от Python, и в этом случае вам придется использовать текстовый формат, нейтральный к языку. И даже здесь вы можете обойтись без рассола плюс инструмент для экспорта.
Если ваш словарь включает в себя ваши собственные объекты (а не только встроенные), у вас могут возникнуть проблемы. В будущей версии вашего кода вы можете изменить имена классов или переместить классы в другие пакеты. Тогда старые данные не будут преобразованы в новый код.
Если у вас есть база данных, я могу предложить сохранить настройки в базе данных. Однако похоже, что обычные файлы лучше подходят для вашей среды.
Вероятно, вы не захотите хранить все пользовательские настройки в одном файле, потому что вы можете столкнуться с проблемами при одновременном доступе к этому единственному файлу. Если бы вы сохранили настройки каждого пользователя в виде словаря в их собственном обработанном файле, то они могли бы действовать независимо.
Травление - разумный способ хранить такие данные, но, к сожалению, формат данных соления, как известно, не читается человеком. Возможно, вам лучше сохранить его как repr(dictionary), который будет более читаемым форматом. Чтобы перезагрузить пользовательские настройки, используйте eval(open("file").read()) или что-то в этом роде.
Я не решаюсь на вопрос, какой из них лучше. Если вы хотите обрабатывать текстовые файлы, я бы рассмотрел ConfigParser -module. Другой вариант, который вы можете попробовать, - это simplejson или ямл. Вы также можете рассмотреть настоящую таблицу db.
Например, у вас может быть таблица с именем userattrs с тремя столбцами:
Если их немного, вы можете сохранить их в куки для быстрого поиска.
Вот самый простой способ. Используйте простые переменные и import файл настроек.
Назовите файл userprefs.py
# a user prefs file
color = 0x010203
font = "times new roman"
position = ( 12, 13 )
size = ( 640, 480 )
В вашем приложении вы должны быть уверены, что можете импортировать этот файл. У вас есть выбор много.
Используя PYTHONPATH. Требовать, чтобы PYTHONPATH включал каталог с файлами настроек.
а. Явный параметр командной строки для имени файла (не лучший, но простой)
б. Переменная среды для имени файла.
Расширение sys.path для включения домашнего каталога пользователя
Пример
import sys
import os
sys.path.insert(0,os.path.expanduser("~"))
import userprefs
print userprefs.color
Разве тогда не нужно было бы иметь отдельный файл для каждого пользователя? Это похоже на большие накладные расходы.
@Mark Biek: «У этих пользователей будет ряд настроек». Для меня это звучит как индивидуальные настройки. Возможно, вы неправильно поняли вопрос.
Я проголосовал за это, потому что это отличное решение моей проблемы - а это не совсем то, о чем задается вопрос. Мне нужен файл конфигурации для приложения командной строки, что является совершенно другим вариантом использования.
Если человеческая читаемость конфигурационных файлов имеет значение, альтернативой может быть модуль ConfigParser, которая позволяет вам читать и записывать файлы, подобные .ini. Но тогда вы ограничены одним уровнем вложенности.
Есть ли конкретная причина, по которой вы не используете для этого базу данных? это кажется нормальным и естественным делом - или сохранить набор настроек в базе данных с ключом пользователя или что-то в этом роде.
Вы не описали шаблоны использования веб-сайта, а просто думаете об общем веб-сайте, но я думаю, что сохранение настроек в базе данных вызовет гораздо меньше операций ввода-вывода на диск, чем использование файлов.
OTOH для настроек, которые могут использоваться клиентским кодом, было бы удобно хранить их как javascript в статическом файле, который можно кэшировать - за счет наличия нескольких мест, где у вас могут быть настройки. (Я бы, вероятно, сохранил эти настройки в базе данных и при необходимости перестроил статические файлы)
Я согласен с ответом об использовании Pickled Dictionary. Очень просто и эффективно для хранения простых данных в структуре словаря.
Если вас не волнует возможность редактировать файл самостоятельно и вам нужен быстрый способ сохранения объектов Python, используйте соленый огурец. Если вы хотите, чтобы файл был доступен для чтения человеком или другим приложением, используйте ConfigParser. Если вам нужно что-то более сложное, используйте какую-нибудь базу данных, будь то реляционная (sqlite) или объектно-ориентированная (аксиома, Zodb).
Конечно, для веб-сайта, управляемого базой данных, лучшим вариантом является таблица db. Я предполагаю, что вы не занимаетесь базой данных.
Если вас не интересуют форматы, удобочитаемые человеком, то pickle - это простой и понятный способ. Я также слышал хорошие отзывы о simplejson.
Если удобочитаемость важна, есть два простых варианта:
Модуль: Просто используйте модуль. Если все, что вам нужно, это несколько глобалов и ничего особенного, то это то, что вам нужно. Если вы действительно отчаялись, вы могли бы определить классы и переменные классов для имитации разделов. Обратной стороной здесь является то, что если файл будет вручную редактироваться пользователем, ошибки может быть трудно выявить и отладить.
Формат INI: Я использовал для этого ConfigObj, и добился некоторого успеха. ConfigObj по сути является заменой ConfigParser с поддержкой вложенных разделов и многого другого. При желании вы можете определить ожидаемые типы или значения для файла и проверить его, обеспечивая безопасность (и важную обратную связь об ошибках) для пользователей / администраторов.
Я бы использовал модуль ConfigParser, который выдает довольно читаемый и редактируемый пользователем вывод для вашего примера:
[bob] colour_scheme: blue british: yes [joe] color_scheme: that's 'color', silly! british: no
Следующий код создаст указанный выше файл конфигурации, а затем распечатает его:
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
Обратите внимание, что ConfigParser поддерживает только строки, поэтому вам придется преобразовать, как я сделал выше для логических значений. См. эффбот для хорошего изучения основ.
Встроенный модуль sqlite3, вероятно, будет намного проще, чем большинство альтернатив, и подготовит вас к обновлению до полной РСУБД, если вы когда-нибудь захотите или захотите.
Проблема с cPickle в этом случае заключается в том, что вы не можете загрузить настройки только для одного пользователя, вы должны загрузить их все. полка лучше масштабируется и не менее проста в использовании.