Использование файла для хранения аргументов optparse
Я использую optparse какое-то время и хочу добавить возможность загружать аргументы из файла конфигурации.
Пока лучшее, что я могу придумать, это пакет обертки script с аргументами hardcoded... кажется неуклюжим.
Каков самый элегантный способ сделать это?
Ответы
Ответ 1
Я согласен с идеей S.Lott использовать файл конфигурации, но я бы рекомендовал использовать встроенный ConfigParser (configparser в 3.0) для его анализа, а не для домашнего решения.
Здесь кратко script, который иллюстрирует ConfigParser и optparse в действии.
import ConfigParser
from optparse import OptionParser
CONFIG_FILENAME = 'defaults.cfg'
def main():
config = ConfigParser.ConfigParser()
config.read(CONFIG_FILENAME)
parser = OptionParser()
parser.add_option("-l",
"--language",
dest="language",
help="The UI language",
default=config.get("Localization", "language"))
parser.add_option("-f",
"--flag",
dest="flag",
help="The country flag",
default=config.get("Localization", "flag"))
print parser.parse_args()
if __name__ == "__main__":
main()
Вывод:
(<Values at 0x2182c88: {'flag': 'japan.png', 'language': 'Japanese'}>, [])
Запустите с помощью "parser.py --language=French
":
(<Values at 0x2215c60: {'flag': 'japan.png', 'language': 'French'}>, [])
Создана справка.
Выполнить с "parser.py --help
":
Usage: parser.py [options]
Options:
-h, --help show this help message and exit
-l LANGUAGE, --language=LANGUAGE
The UI language
-f FLAG, --flag=FLAG The country flag
Файл конфигурации:
[Localization]
language=Japanese
flag=japan.png
Ответ 2
Вы можете использовать argparse
для этого:
>>> open('args.txt', 'w').write('-f\nbar')
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
>>> parser.add_argument('-f')
>>> parser.parse_args(['-f', 'foo', '@args.txt'])
Namespace(f='bar')
Он может быть включен в stdlib, см. pep 389.
Ответ 3
У меня была аналогичная проблема, но также хотелось указать конкретный файл конфигурации в качестве аргумента. Вдохновленный ответом С. Лотта, я придумал следующий код.
Пример сеанса терминала:
$ python defaultconf.py # use hard-coded defaults
False
$ python defaultconf.py --verbose # verbose on command line
True
$ python defaultconf.py --loadconfig blah # load config with 'verbose':True
True
$ python defaultconf.py --loadconfig blah --quiet # Override configured value
False
код:
#!/usr/bin/env python2.6
import optparse
def getParser(defaults):
"""Create and return an OptionParser instance, with supplied defaults
"""
o = optparse.OptionParser()
o.set_defaults(**defaults)
o.add_option("--verbose", dest = "verbose", action="store_true")
o.add_option("--quiet", dest = "verbose", action="store_false")
o.add_option("--loadconfig", dest = "loadconfig")
return o
def main():
# Hard coded defaults (including non-command-line-argument options)
my_defaults = {'verbose': False, 'config_only_variable': 42}
# Initially parse arguments
opts, args = getParser(my_defaults).parse_args()
if opts.loadconfig is not None:
# Load config from disk, update the defaults dictionary, and reparse
# Could use ConfigParser, simplejson, yaml etc.
config_file_values = {'verbose': True} # the dict loaded from disk
my_defaults.update(config_file_values)
opts, args = getParser(my_defaults).parse_args()
print opts.verbose
if __name__ == '__main__':
main()
Практическая реализация может быть найдена в Github: Словарь по умолчанию, парсер аргументов и основная функция
Ответ 4
Для чего предназначена функция set_defaults
. http://docs.python.org/library/optparse.html#optparse.OptionParser.set_defaults
Создайте файл, который содержит значения по умолчанию.
{ 'arg1': 'this',
'arg2': 'that'
}
Затем прочитайте этот файл, eval его, чтобы преобразовать текст в словарь и предоставить этот словарь в качестве аргументов set_defaults
.
Если вы действительно обеспокоены eval
, используйте JSON (или YAML) для этого файла. Или вы даже можете сделать из него .INI
файл и использовать configparser
, чтобы получить свои значения по умолчанию.
Или вы можете использовать простой список операторов присваивания и exec
.
Файл конфигурации.
arg1 = 'this'
arg2 = 'that'
Чтение конфигурационного файла.
defaults= {}
with open('defaults.py','r') as config
exec config in {}, defaults
Ответ 5
Прочитайте аргументы в том же формате командной строки из файла, например. @commands, затем используйте свой оригинальный синтаксический анализатор для их анализа.
options, args = parser.parse_args()
if args[0][0] == '@': # script.py @optfile
with open(args[0][1:]) as f:
fa = [l.strip() for l in f]
fa = fa + args[1:] # put back any other positional arguments
# Use your original parser to parse the new options
options, args = parser.parse_args(args=fa, values=options)
Ответ 6
В последнее время я создал много скриптов с флагами и параметрами, и я придумал решение, описанное здесь.
В основном я экземпляр optionparser со специальным флагом, который сообщает, чтобы попробовать и загрузить параметры из файла, поэтому вы можете обычно использовать свои параметры script из командной строки или предоставить их (или их набор) из файла.
Обновление: у меня есть общий код на GitHub