Как лучше всего использовать файл настроек в Python? [закрыто]


332

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

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

Несколько «требований»:

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

Упрощенный файл псевдо-примера:

truck:
    color: blue
    brand: ford
city: new york
cabriolet:
    color: black
    engine:
        cylinders: 8
        placement: mid
    doors: 2

6
Конкретный синтаксис этого примера файла на самом деле YAML, проверьте ответ Бенсона.
— Скиппи ле Гран Гуру

Ответы:


231

У вас может быть обычный модуль Python, скажем config.py, например:

truck = dict(
    color = 'blue',
    brand = 'ford',
)
city = 'new york'
cabriolet = dict(
    color = 'black',
    engine = dict(
        cylinders = 8,
        placement = 'mid',
    ),
    doors = 2,
)

и используйте это так:

import config
print config.truck['color']  

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

172
Разрешение «пользователям с низким уровнем привилегий» изменять конфигурацию для более привилегированной программы, вероятно, в любом случае является сомнительной установкой.
— XTL

18
Вы также можете столкнуться с проблемами упаковки вашего проекта для развертывания с помощью такого инструмента, как py2app. Пользователь может не иметь возможности редактировать файл конфигурации после его распространения, поскольку это сделает недействительной подпись приложения.
— bschwagg

18
Основным недостатком этого (в противном случае очень удобный вариант) является то, что .pyфайлы являются исполняемыми, поэтому любой код может быть запущен при попытке загрузить конфигурацию import. Это неприемлемо с точки зрения безопасности.
— Апалала

5
Разве версия этого не может быть безопасно сделана ast.literal_eval? docs.python.org/3/library/ast.html#ast.literal_eval
— Андре С. Андерсен

169

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

Использовать модуль yaml чрезвычайно просто:

import yaml
config = yaml.safe_load(open("path/to/config.yml"))

3
ямл - это всегда то, к чему я обращаюсь; формат может быть от простого до поддержки встроенного кода Python, а стандартная библиотека выполняет тяжелую работу по разбору и обработке.
— Тодор Минаков

15
Согласовано. Для вас или пользователей, пишущих YAML, вот лучшая из известных мне ссылок на YAML . К сожалению, официальная документация - это спецификация, предназначенная для разработчиков, и ничто иное, но руководство Eevee просто фантастическое.
— Esteis

5
Для нас, непосвященных, pip3 install pyyamlэто готово для импорта в скрипты Python.
— user8675309

2
Осторожно, yaml дружелюбен только в том случае, если вы сохраняете его очень простым, по умолчанию он содержит множество проблем, граничащих с небезопасными функциями. Вместо этого попробуйте hitchdev.com/strictyaml в качестве безопасной альтернативы по умолчанию.
— Gringo Suave

См. Мунк , stackoverflow.com/questions/52570869/… import yaml; from munch import munchify; f = munchify(yaml.load(…)); print(fo.d.try)
— Ганс Гинзель

107

Я нашел это наиболее полезным и простым в использовании https://wiki.python.org/moin/ConfigParserExamples

Вы просто создаете "myfile.ini", например:

[SectionOne]
Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True

[SectionTwo]
FavoriteColor=Green
[SectionThree]
FamilyName: Johnson

[Others]
Route: 66

И получить данные как:

>>> import ConfigParser
>>> Config = ConfigParser.ConfigParser()
>>> Config
<ConfigParser.ConfigParser instance at 0x00BA9B20>
>>> Config.read("myfile.ini")
['c:\\tomorrow.ini']
>>> Config.sections()
['Others', 'SectionThree', 'SectionOne', 'SectionTwo']
>>> Config.options('SectionOne')
['Status', 'Name', 'Value', 'Age', 'Single']
>>> Config.get('SectionOne', 'Status')
'Single'

20
Для Python 3 вместо этого используйте модуль configparser (все строчные буквы)
— Roland

2
Это самое быстрое, понятное и простое в реализации решение, поскольку здесь нет реализации, только использование. :) Спасибо!
— Александар

Будет ли это поддерживать вложенные словари, как указано в вопросе?
— Якуб Блаха

54

Yaml и Json - самые простые и наиболее часто используемые форматы файлов для хранения настроек / конфигурации. PyYaml может быть использован для разбора yaml. Json уже является частью Python с 2.5. Yaml - это суперсет Json. Json решит большинство случаев использования, за исключением многострочных строк, где требуется экранирование. Yaml тоже заботится об этих случаях.

>>> import json
>>> config = {'handler' : 'adminhandler.py', 'timeoutsec' : 5 }
>>> json.dump(config, open('/tmp/config.json', 'w'))
>>> json.load(open('/tmp/config.json'))   
{u'handler': u'adminhandler.py', u'timeoutsec': 5}

13
Хотя json более или менее эквивалентен, он не так удобен для чтения, как yaml. Поскольку его пример конфигурации действительно действителен yaml, я бы подчеркнул, что вместо json.
— Бенсон

23
Использование «json.dump (config, fp, sort_keys = True, indent = 4)» улучшает читабельность.
— Фоби

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.