Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何防止带有选项的可选参数多次出现_Python_Argparse - Fatal编程技术网

Python 如何防止带有选项的可选参数多次出现

Python 如何防止带有选项的可选参数多次出现,python,argparse,Python,Argparse,我在Python2.7中使用argparse。我想阻止用户使用多个参数调用my_app.py --缓存可选参数-cache(或--cache)是带有选项的可选参数,具有常量和默认值。守则: parser = argparse.ArgumentParser() parser.add_argument("-cache","-- cache",required=False,const='all',default=None,nargs='?',choices=["server-only","local

我在Python2.7中使用argparse。我想阻止用户使用多个参数调用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

在这个类似的问题中没有充分的答案。在链接中,您可以定义一个自定义操作,第一次使用该选项时“记住”,然后在第二次使用时引发异常

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)

一种解决方案是将选项值保存在列表中。然后,在解析完选项后,检查列表长度,如果是2或更多,则给出一个错误。使用
action=“append”
default=[]
在列表中收集选项值。@TomKarzes-非常好的快速答案。在我发布我的问题之前,我已经尝试过完全遵循这个概念(同样的想法),并且我已经将默认设置更改为保留一个列表,但我唯一错过的是action=“apend”!谢谢。默认的
argparse
行为是将
default
放在名称空间中,然后允许每个实例对其进行重写,实际上是最后一个用户提供的值(如果有)。为什么要反抗?您的用户是否特别喜欢出于某种特殊目的使用
--cache--cache=foobar
。这让我想起了设计模式中的一条坚实原则(四人帮)——开放供扩展,关闭供修改。您可以很好地扩展类。谢谢。在类OneTimeAction中,在基类的方法调用中,基类的真正签名是:_call___;(self,parser,namespace,value,option_string=None),因此python将阻止您这样做。您需要从super呼叫中删除**KWARGmethod@Adam如果你不传递任何额外的关键字,它就没有效果。接受未知的关键字参数并传递它们是正确使用
super
的标志之一。您编写的第一个函数调用是错误的def\uuu call\uuuuuuuu(self,parser,namespace,values,option\u string=None,**kwargs)!不管怎样,你已经修好了!非常感谢。我仍然对*args和**kwargs感到困惑,如果你有一个好的教程链接,我将不胜感激。(对于高级案例(例如您在这里使用的案例,而不是像这样的标准教程),例如,为什么python在同一个函数中使用其内置函数,例如def foo(*args,**kwargs)??为什么不单独使用**kwargs!?如果您单独使用
**kwargs
,则调用者必须将所有参数作为关键字参数传递。