Использование файла для хранения аргументов 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