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

StackOverflow https://stackoverflow.com/questions/200599

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

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

[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 поддерживает только строки, поэтому вам придется преобразовать логические значения, как я описал выше.Видишь эффективный робот для хорошего изложения основ.

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

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

  • Внутренний идентификатор пользователя
  • Строковое имя_атрибута
  • Строковый атрибут value

Если их немного, вы могли бы сохранить их в файлах cookie для быстрого извлечения.

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

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

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

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

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

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

    b.Переменная среды для присвоения имени файлу.

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

Пример

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

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

Если вас не волнуют удобочитаемые форматы, то pickle это простой и прямолинейный путь.Я также слышал хорошие сообщения о simplejson.

Если важна удобочитаемость для человека, напрашиваются два простых варианта:

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

Формат INI: Я использовал ConfigObj ( Конфигурационный файл) для этого, с немалым успехом.ConfigObj - это, по сути, замена ConfigParser, с поддержкой вложенных разделов и многого другого.При необходимости вы можете определить ожидаемые типы или значения для файла и проверить его, обеспечивая систему безопасности (и важную обратную связь об ошибках) для пользователей / администраторов.

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

Встроенный sqlite3 модуль, вероятно, будет намного проще большинства альтернатив и подготовит вас к обновлению до полноценной СУБД, если вы когда-нибудь захотите или в этом возникнет необходимость.

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

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

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

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

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

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

OTOH, для настроек, которые могут использоваться клиентским кодом, было бы удобно сохранить их как javascript в статическом файле, который можно кэшировать, за счет наличия нескольких мест, где у вас могут быть настройки.(Я бы, вероятно, сохранил эти настройки в базе данных и перестроил статические файлы по мере необходимости)

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

Если вас не волнует возможность редактировать файл самостоятельно и вам нужен быстрый способ сохранения объектов python, используйте маринованный огурец.Если вы хотите, чтобы файл был доступен для чтения человеку или какому-либо другому приложению, используйте Конфигурационный анализатор.Если вам нужно что-то более сложное, используйте какую-нибудь базу данных, будь то реляционная (sqlite - файл), или объектно-ориентированный (аксиома, зодб).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top