Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.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 Argparse:指定可选参数时忽略多个位置参数_Python_Argparse - Fatal编程技术网

Python Argparse:指定可选参数时忽略多个位置参数

Python Argparse:指定可选参数时忽略多个位置参数,python,argparse,Python,Argparse,我试图让argparse忽略一个事实,即当指定可选参数(-l)时,不应计算两个通常需要的位置参数 基本上,我试图复制--help的行为:当您指定-h时,所有缺少的必需参数都将被忽略 示例代码: parser = argparse.ArgumentParser(description="Foo bar baz") parser.add_argument('arg1', help='arg1 is a positional argument that does this') parser.add_a

我试图让argparse忽略一个事实,即当指定可选参数(
-l
)时,不应计算两个通常需要的位置参数

基本上,我试图复制--help的行为:当您指定-h时,所有缺少的必需参数都将被忽略

示例代码:

parser = argparse.ArgumentParser(description="Foo bar baz")
parser.add_argument('arg1', help='arg1 is a positional argument that does this')
parser.add_argument('arg2', help='arg2 is a positional argument that does this')
parser.add_argument('-l', '--list', dest='list', help='this is an optional argument that prints stuff')

options, args = parser.parse_args()

if options.list:
   print "I list stuff"
当然,如果我现在运行它,我会得到:

error: too few arguments
我尝试了不同的方法,比如
nargs='?'
,但都没有成功


非常类似,但没有得到回答。

不幸的是,
argparse
对此不够灵活。您最好使用
nargs=“?”
arg1
arg2
设置为可选,并检查是否在需要时提供了它们

通过打印帮助消息并在命令行上遇到
-h
--help
时立即退出程序,即可执行内部
帮助
操作。你可以自己写一个类似的动作,比如

class MyAction(argparse.Action):
    def __call__(self, parser, values, namespace, option_string):
        print "Whatever"
        parser.exit()
(警告:未测试的代码!)


不过,后一种方法肯定有缺点。帮助消息将无条件地将
arg1
arg2
显示为强制参数。当遇到
-l
--list
时,解析命令行就会停止,忽略任何其他参数。这种行为对于
--help
是可以接受的,但对于其他选项则不太理想。

我遇到了这个问题,决定使用子命令。子命令可能有些过分,但如果您发现您的程序在许多实例中没有使用某些位置参数(正如我所做的),那么子命令可能是一个很好的解决方案

对于您给定的示例,我将使用如下内容:

parser = argparse.ArgumentParser(description="Foo bar baz")
subparsers = parser.add_subparsers(description='available subcommands')

parser_main = subparsers.add_parser('<main_command_name>')
parser_main.add_argument('arg1', help='arg1 is a positional argument that does this')
parser_main.add_argument('arg2', help='arg2 is a positional argument that does this')

parser_list = subparsers.add_parser('list', help='this is a subcommand that prints stuff')

options, args = parser.parse_args()
parser=argparse.ArgumentParser(description=“Foo-bar-baz”)
subparsers=parser.add_subparsers(description='available subcommands')
parser_main=子parsers.add_parser(“”)
parser_main.add_参数('arg1',help='arg1是执行此操作的位置参数')
parser_main.add_参数('arg2',help='arg2是执行此操作的位置参数')
parser_list=subparsers.add_parser('list',help='这是一个打印内容的子命令〕
选项,args=parser.parse_args()

我遗漏了一些您可能想要包括的细节(比如
set\u defaults(func=list)
),它们在中提到。

我认为
nargs='*'
是有帮助的

位置参数是可忽略的,则可以使用
if
检查位置参数是否为真


我可能在这里找到了解决办法。诚然,这是一个肮脏的黑客,但它的工作

注意:以下所有内容都适用于Python 3.3.2。

根据答案,
parse_args
检查哪些操作是必需的,如果缺少任何操作,则抛出错误。我提议推翻这种行为

通过子类化
ArgumentParser
,我们可以定义一个新的
ArgumentParser.error
方法(原始),该方法将检查是否由于缺少某些参数而引发错误,并采取必要的措施。代码如下:

import argparse
导入系统
从gettext导入gettext作为_
类ArgumentParser(argparse.ArgumentParser):
跳过列表=[]
def错误(自我,消息):
#让我们看看我们是否缺少参数
if message.startswith('需要以下参数:'):
missingArgs=message.split('required:')[1]。split(','))
newArgs=[]#创建一个列表,列出我们不应跳过但缺少的内容
对于缺失args中的arg:
如果arg不在self.skip_列表中:
newArgs.append(arg)
其他:
self.skip_list.remove(arg)#不再需要它
如果len(newArgs)==0:
返回#警告!未经测试!可能会导致时空崩溃!
else:#某些必需的内容仍然丢失,因此我们显示一条更正的错误消息
message=(('需要以下参数:%s')%,'。join(newArgs)
self.print_用法(sys.stderr)#原始方法行为
args={'prog':self.prog,'message':message}
self.exit(2,u('%(prog)s:error:%(message)s\n')%args)
新方法首先检查错误是否是因为命令行中缺少参数所致(有关生成错误的代码,请参阅)。如果是这样,该方法将从错误消息中获取参数的名称,并将它们放入列表(
missingArgs

然后,我们迭代这个列表并检查哪些参数应该被跳过,哪些仍然是必需的。为了确定要跳过哪些参数,我们将它们与
skip\u list
进行比较。它是
ArgumentParser
子类中的一个字段,应该包含要跳过的参数的名称,即使解析器需要它们。请注意,当找到恰好位于
跳过列表
中的参数时,这些参数将从列表中删除

如果命令行中仍然缺少必需的参数,则该方法将抛出一条已更正的错误消息。但是,如果应跳过所有缺少的参数,则该方法将返回

警告ArgumentParser.error的原始定义指出,如果在子类中重写它,则不应返回,而应退出或引发异常。因此,此处显示的内容可能不安全,并可能导致程序崩溃、计算机起火或更糟-它可能会蒸发掉您所有的茶。但是,在这种特殊情况下(缺少必需的参数),从方法返回似乎是安全的。但可能不是这样。你已经被警告了

为了填写
跳过列表
,我们可以使用如下代码:

class-SpecialH
def print_list():
    the_list = ["name1", "name2"]
    return "{0}".format(the_list)

...
parser.add_argument("-l", "--list", action='version',
                    version=print_list(), help="print the list")
parser = argparse.ArgumentParser(description="Foo bar baz")
parser.add_argument('-l', '--list', dest='list', action='store_true',
                    help='this is an optional argument that prints stuff')

options, remainder = parser.parse_known_args()
if options.list:
    print "I list stuff"
else:
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument('arg1', help='arg1 is a positional argument that does this')
    parser.add_argument('arg2', help='arg2 is a positional argument that does this')
    options = parser.parse_args(remainder)