Как предотвратить множественное вхождение необязательного аргумента с выбором - PullRequest
1 голос
/ 30 апреля 2020

Я использую argparse в python 2.7. Я хотел бы запретить пользователю вызывать my_app.py с необязательным аргументом --cache. -cache (или --cache) является необязательным аргументом с возможностью выбора и имеет значения const и default. код:

parser = argparse.ArgumentParser()
parser.add_argument("-cache","-- 
cache",required=False,const='all',default=None,nargs='?',choices=["server-only","local-only","all"], 
help="Activate Cache by choosing one of the list choices. e.g. -cache=local-only")

Я хочу вызвать исключение, когда пользователь вызывает my_app.py в приведенной ниже форме:

#if he calls with multiple --cache arguments, argparse takes the last dilvered one !! But i want to 
raise an exception here!
my_app.py --cache --cache=server-only

В этом аналогичном вопросе не было найдено достаточно убедительного ответа. ссылка вхождение нескольких аргументов

1 Ответ

3 голосов
/ 30 апреля 2020

Вы можете определить настраиваемое действие, которое «запоминает» при первом использовании параметра, а затем вызывает исключение, если оно используется второй раз.

import argparse


class OneTimeAction(argparse._StoreAction):
    def __init__(self, *args, **kwargs):
        super(OneTimeAction, self).__init__(*args, **kwargs)
        self.seen = False

    def __call__(self, *args, **kwargs):
        if self.seen:
            parser = args[0]
            option_string = args[3]
            parser.error("Cannot use {} a second time".format(option_string))
        super(OneTimeAction, self).__call__(*args, **kwargs)
        self.seen = True


parser = argparse.ArgumentParser()
parser.add_argument("-cache", "--cache", 
                    action=OneTimeAction,
                    default="all",
                    choices=["server-only", "local-only", "all"],
                    help="Activate Cache by choosing one of the list choices. e.g. -cache=local-only")

В более общем случае вы можете определить это как смешивание, которое будет использоваться с любым видом действия. Следующий пример также сворачивает большую часть конфигурации аргумента в собственное настраиваемое действие.

import argparse


class OneTimeMixin(object):
    def __init__(self, *args, **kwargs):
        super(OneTimeMixin, self).__init__(*args, **kwargs)
        self.seen = False

    def __call__(self, *args, **kwargs):
        if self.seen:
            parser = args[0]
            option_string = args[3]
            parser.error("Cannot use {} a second time".format(option_string))
        super(OneTimeMixin, self).__call__(*args, **kwargs)
        self.seen = True


class CacheAction(OneTimeMixin, argparse._StoreAction):
    def __init__(self, *args, **kwargs):
        # setdefault ensures you can override these if desired
        kwargs.setdefault('choices', ["server-only", "local-only", "all"])
        kwargs.setdefault('default', 'all')
        kwargs.setdefault('help', "Activate Cache by choosing one of the list choices. e.g. -cache=local-only")
        super(CacheAction, self).__init__(*args, **kwargs)


parser = argparse.ArgumentParser()
parser.add_argument("-cache", "--cache", action=CacheAction)
...