Добавете аргументи на 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() независимо дали има стойност или е None:

            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