首页 > 解决方案 > 如何防止多次出现带有选项的可选参数

问题描述

我在 python 2.7 中使用 argparse。我想阻止用户使用多个 --cache 可选参数调用 my_app.py 。-cache(或--cache)是带有选项的可选参数,有一个常量和一个默认值。编码:

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

在这个类似的问题中没有足够的答案。在链接多参数出现中

标签: pythonargparse

解决方案


您可以定义一个自定义操作,在第一次使用该选项时“记住”该选项,然后在第二次使用时引发异常。

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)

推荐阅读