Храните простые пользовательские настройки в Python

Я программирую веб-сайт, на котором у пользователей будет ряд настроек, таких как выбор цветовой схемы и т. д. Я счастлив хранить их в виде текстовых файлов, и безопасность не является проблемой.

В настоящее время я вижу это так: есть словарь, где все ключи - это пользователи, а значения - это словари с пользовательскими настройками в них.

Например, userdb ["bob"] ["colour_scheme"] будет иметь значение "blue".

Как лучше всего хранить его в файле? Травление словаря?

Есть ли лучшие способы делать то, что я пытаюсь сделать?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
7
0
9 844
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

Ответ принят как подходящий

Я бы предпочел использовать cPickle в словаре. Словари естественным образом подходят для такого рода данных, поэтому, учитывая ваши требования, я не вижу причин не использовать их. Это, если вы не думаете о чтении их из приложений, отличных от Python, и в этом случае вам придется использовать текстовый формат, нейтральный к языку. И даже здесь вы можете обойтись без рассола плюс инструмент для экспорта.

Проблема с cPickle в этом случае заключается в том, что вы не можете загрузить настройки только для одного пользователя, вы должны загрузить их все. полка лучше масштабируется и не менее проста в использовании.

Toni Ruža 16.10.2008 11:00

Если ваш словарь включает в себя ваши собственные объекты (а не только встроенные), у вас могут возникнуть проблемы. В будущей версии вашего кода вы можете изменить имена классов или переместить классы в другие пакеты. Тогда старые данные не будут преобразованы в новый код.

ChrisCantrell 30.05.2014 23:22

Если у вас есть база данных, я могу предложить сохранить настройки в базе данных. Однако похоже, что обычные файлы лучше подходят для вашей среды.

Вероятно, вы не захотите хранить все пользовательские настройки в одном файле, потому что вы можете столкнуться с проблемами при одновременном доступе к этому единственному файлу. Если бы вы сохранили настройки каждого пользователя в виде словаря в их собственном обработанном файле, то они могли бы действовать независимо.

Травление - разумный способ хранить такие данные, но, к сожалению, формат данных соления, как известно, не читается человеком. Возможно, вам лучше сохранить его как repr(dictionary), который будет более читаемым форматом. Чтобы перезагрузить пользовательские настройки, используйте eval(open("file").read()) или что-то в этом роде.

Я не решаюсь на вопрос, какой из них лучше. Если вы хотите обрабатывать текстовые файлы, я бы рассмотрел ConfigParser -module. Другой вариант, который вы можете попробовать, - это simplejson или ямл. Вы также можете рассмотреть настоящую таблицу db.

Например, у вас может быть таблица с именем userattrs с тремя столбцами:

  • Int user_id
  • String attribute_name
  • Строка attribute_value

Если их немного, вы можете сохранить их в куки для быстрого поиска.

Вот самый простой способ. Используйте простые переменные и import файл настроек.

Назовите файл userprefs.py

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

В вашем приложении вы должны быть уверены, что можете импортировать этот файл. У вас есть выбор много.

  1. Используя PYTHONPATH. Требовать, чтобы PYTHONPATH включал каталог с файлами настроек.

    а. Явный параметр командной строки для имени файла (не лучший, но простой)

    б. Переменная среды для имени файла.

  2. Расширение sys.path для включения домашнего каталога пользователя

Пример

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

Разве тогда не нужно было бы иметь отдельный файл для каждого пользователя? Это похоже на большие накладные расходы.

Mark Biek 14.10.2008 18:11

@Mark Biek: «У этих пользователей будет ряд настроек». Для меня это звучит как индивидуальные настройки. Возможно, вы неправильно поняли вопрос.

S.Lott 14.10.2008 18:50

Я проголосовал за это, потому что это отличное решение моей проблемы - а это не совсем то, о чем задается вопрос. Мне нужен файл конфигурации для приложения командной строки, что является совершенно другим вариантом использования.

Joe Germuska 27.08.2009 06:11

Если человеческая читаемость конфигурационных файлов имеет значение, альтернативой может быть модуль ConfigParser, которая позволяет вам читать и записывать файлы, подобные .ini. Но тогда вы ограничены одним уровнем вложенности.

Я бы использовал базу данных полка или sqlite, если бы мне пришлось хранить эти настройки в файловой системе. Хотя, поскольку вы создаете веб-сайт, вы, вероятно, используете какую-то базу данных, так почему бы просто не использовать ее?

Есть ли конкретная причина, по которой вы не используете для этого базу данных? это кажется нормальным и естественным делом - или сохранить набор настроек в базе данных с ключом пользователя или что-то в этом роде.

Вы не описали шаблоны использования веб-сайта, а просто думаете об общем веб-сайте, но я думаю, что сохранение настроек в базе данных вызовет гораздо меньше операций ввода-вывода на диск, чем использование файлов.

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, вероятно, будет намного проще, чем большинство альтернатив, и подготовит вас к обновлению до полной РСУБД, если вы когда-нибудь захотите или захотите.

Другие вопросы по теме