Добавить аргументы argparse из внешних модулей

Я пытаюсь написать программу Python, которую можно расширить третьими лицами. Программа будет запущена из командной строки с любыми аргументами.

Чтобы третьи стороны могли создавать свои собственные модули, я создал следующий (упрощенный) базовый класс:

class MyBaseClass(object):
    def __init__(self):
        self.description = ''
        self.command = ''

    def get_args(self):
        # code that I can't figure out to specify argparse arguments here
        # args = []
        # arg.append(.....)
        return args

Любые аргументы, которые они передают через get_args(), будут добавлены в подпарсер для этого конкретного модуля. Я хочу, чтобы они могли указать любой тип аргумента.

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

Вот текущий код из основной программы:

for module in find_modules():
    m = module()
    subparser_dict[module.__name__] = subparsers.add_parser(m.command, help=m.help)
    for arg in m.get_args():
            subparser_dict[module.__name__].add_argument(...)

Как мне лучше указать аргументы во внешних модулях через get_args() или что-то подобное, а затем добавить их в подпарсер? Одна из моих неудачных попыток выглядела следующим образом, которая не работает, потому что она пытается передать все возможные опции в add_argument() независимо от того, имеет ли она значение или нет:

            subparser_dict[module.__name__].add_argument(arg['long-arg'],
                action=arg['action'],
                nargs=arg['nargs'],
                const=arg['const'],
                default=arg['default'],
                type=arg['type'],
                choices=arg['choices'],
                required=arg['required'],
                help=arg['help'],
                metavar=arg['metavar'],
                dest=arg['dest'],
                )

person doza    schedule 25.05.2014    source источник


Ответы (2)


Не пытаясь полностью понять структуру вашего модуля, я думаю, вы хотите иметь возможность предоставлять аргументы для вызова add_argument в виде объектов, которые вы можете импортировать.

Вы можете, например, предоставить список позиционных аргументов и словарь аргументов ключевого слова:

args=['-f','--foo']
kwargs={'type':int, 'nargs':'*', 'help':'this is a help line'}

parser=argparse.ArgumentParser()
parser.add_argument(*args, **kwargs)
parser.print_help()

производство

usage: ipython [-h] [-f [FOO [FOO ...]]]

optional arguments:
  -h, --help            show this help message and exit
  -f [FOO [FOO ...]], --foo [FOO [FOO ...]]
                        this is a help line

В argparse.py метод add_argument (суперкласса ArgumentParser) имеет эту общую сигнатуру

def add_argument(self, *args, **kwargs):

Код этого метода манипулирует этими аргументами, добавляет args к kwargs, добавляет значения по умолчанию и, в конце концов, передает kwargs соответствующему классу Action, возвращая новое действие. (Он также «регистрирует» действие в анализаторе или подпарсере). Это __init__ подклассов Action, в котором перечислены аргументы и их значения по умолчанию.

person hpaulj    schedule 25.05.2014

Я бы просто вернул экземпляр ArgumentParser из вашего метода get_args. Затем вы можете создать новый ArgumentParser, чтобы присоединиться ко всем другим анализаторам аргументов, используя аргумент parents: https://docs.python.org/3/library/argparse.html#parents.

person SCGH    schedule 25.09.2017