Python Argparse:指定可选参数时忽略多个位置参数
我试图让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
-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)