2013-05-22 4 views
5

Я получил проект от разработчика, который покинул нашу компанию. Не слишком сложный, но это выглядит не очень хорошо. Итак, вот вопрос: Приложение имеет несколько модулей, а одно - «настройки», в котором хранится какое-то приложение. варианты (не все возможные варианты, скажем, всего два: foo и bar). Когда приложение запускается он считывает параметры из командной строки (используя argparse):Как сохранить настройки приложения для всех модулей

parser.add_argument('--foo', action='store_true') 
parser.add_argument('--bar', action='store_true') 
parser.add_argument('--baz', action='store_true') 

И тогда она выполняет эту неприятную вещь:

for name, val in parser.parse_args(sys.argv[1:])._get_kwargs(): 
    setattr(sys.modules['settings'], name, val) 

Первое: Я думаю, что это грязное, без вещий хак , И, во-вторых, это просто неудобно использовать такой код, потому что, когда мне нужно использовать settings.baz, жалобы IDE, которых он не существует. Цель этого взлома заключается в том, чтобы проанализировать параметры из командной строки во всех модулях, которые используются в приложении далее.

Я думаю о чем-то вроде одноэлементного шаблона, но я использовал его только один раз в PHP и не знаю, правильно ли это решение в python. И даже если это так, может кто-нибудь показать пример?

Я ноб в питоне и на SO, пожалуйста, будьте добры ко мне :) Спасибо.

p.s. Я прошу прощения за возможные ошибки в моем английском

+0

Это дубликат. На это был дан ответ в этом разделе http://stackoverflow.com/questions/15992387/python-settings-file –

+9

Это не дубликат, а другой - о файлах конфигурации, это о конфигурации модуля времени выполнения. –

ответ

4

Модулей в Python являются одноэлементными объектами и, используя один для сохранения настроек, используемых других модулями будет очень Pythonic

Вторая строка «противной вещи» просто устанавливает атрибуты модуля с именем settings и так не так уж плохо. Хуже находится часть _get_kwargs() первой строки, которая обращается к частному атрибуту объекта argparse.Namespace, который был возвращен parser.parse_args(), чтобы получить имена и значения параметров, проанализированных из командной строки. Немного лучше способ сделать это может быть что-то вроде этого:

import settings # possibly empty .py file 

for name, val in vars(parser.parse_args(sys.argv[1:])).iteritems(): 
    setattr(settings, name, val) 

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

В первый раз модуль import эд запись для него добавляется в sys.modules словарь с его именем в качестве ключа и экземпляр types.ModuleType в качестве значения. Последующий import s сначала проверяет, существует ли запись для него, и пропустит перезагрузку файла, если это произойдет - поэтому я утверждаю, что они в основном одноэлементные объекты. Изменения, внесенные в его атрибуты, немедленно будут видны другим модулям, которые импортировали его или сделали это впоследствии, поэтому он обычно является хорошим механизмом совместного использования данных в приложении.

+1

Это то, что я искал. Кроме того, я нашел эту [ссылку] (http://docs.python.org/2/faq/programming.html#how-do-i-share-global-variables-across-modules), которая просто подтверждает ваш ответ. Что касается «неприятной вещи» - вы правы, самым запутанным было использование частного метода. Спасибо за подсказку с 'vars'. И, конечно, спасибо за подробное объяснение того, как все это работает. – user2410235

+0

Приятно видеть, что они явно документировали это использование модулей в FAQ. Хотя задачей 'sys.modules' является предоставление механизма кэширования модулей, реализация делает их особенно хорошо подходящими для обмена данными между модулями внутри приложения. – martineau

+1

FWIW Также есть раздел под названием [Как поделиться глобальными переменными между модулями?] (Https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across -модули) в текущей документации Python 3, которая имеет тот же совет (назовите это «каноническим» способом делать такие вещи). – martineau

0
+1

Да, я видел этот модуль, но это скорее прохладный формат конфигурации, чем тот, который мне нужен. Фактически, вопрос заключается в том, как использовать конфигурацию для всех модулей в приложении. Независимо от того, являются ли эти параметры из файла конфигурации или командной строки. Вероятно, я не вижу ничего, и этот модуль имеет то, что мне нужно, но, пожалуйста, обратите внимание: я ноб в python (и не имею слишком большого опыта программирования вообще). Так что было бы неплохо, если бы вы могли указать мне, как использовать его в моем случае. – user2410235

Смежные вопросы