Python 使用nargs='+';
我必须用这样的命令行参数创建一个解析器Python 使用nargs='+';,python,argparse,Python,Argparse,我必须用这样的命令行参数创建一个解析器 python function.py -v 1 name1 -d abc xyz foo bar name2 -i 3 -p abc xyz 我这样做: import argparse parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('-v', type=int, help='number') subparsers = parser.add_subparsers(hel
python function.py -v 1 name1 -d abc xyz foo bar name2 -i 3 -p abc xyz
我这样做:
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-v', type=int, help='number')
subparsers = parser.add_subparsers(help='sub-command help', dest="command")
parser_a = subparsers.add_parser('name1', help="name1 help")
parser_a.add_argument("-d", help="list", nargs="+")
parser_b = subparsers.add_parser('name2', help="name2 help")
parser_b.add_argument("-p", help="list2", nargs='+')
parser_b.add_argument("-i", help="number inside name2", type=int)
当我运行此命令时:
parser.parse_args('-v 1 name1 -d abc xyz foo bar name2 -i 3 -p abc xyz'.split())
其结果是:
usage: PROG [-h] [-v V] {name1,name2} ...
PROG: error: unrecognized arguments: -i 3 -p abc xyz
运行此命令时:
parser.parse_args('-v 1 name1 -d abc xyz foo bar name2'.split())
其结果是:
Namespace(command='name1', d=['abc', 'xyz', 'foo', 'bar', 'name2'], v=1)
我希望它是这样的:
Namespace(command='name1', d=['abc', 'xyz', 'foo', 'bar'], command='name2', p=['abc', 'xyz'], i=3, v=1)
我该怎么做?正如你所说
In [24]: parser.parse_args('-v 1 name1 -d abc xyz foo bar name2'.split())
Out[24]: Namespace(command='name1', d=['abc', 'xyz', 'foo', 'bar', 'name2'], v=1)
name2
被视为解析器a
-d
参数之一
其余的'-i 3-p abc xyz'不被接受,因为-i
被理解为可选标志
实际上,您正在运行:
In [28]: parser_a.parse_args('-d abc xyz foo bar name3 -i 3 -p abc xyz'.split())
usage: PROG name1 [-h] [-d D [D ...]]
PROG name1: error: unrecognized arguments: -i 3 -p abc xyz
主解析器有一个位置参数,它接受两个选项,name1
和name2
。当遇到name1
时,它将其余参数传递给解析器a
净效果是,argparse
只接受一个子命令
我在前面的SO问题中讨论了一些解决方法。侧边栏找到了一个:
(这可能非常适合将此问题标记为重复问题)
如果我向
解析器添加一个位置;并使用--
分隔栏
和名称2
(意思是,后面的内容都是位置)
然后我可以将额外的字符串(减去name2
)传递给parser\b
:
In [34]: args=_
In [36]: parser_b.parse_args(args.extra[1:])
Out[36]: Namespace(i=3, p=['abc', 'xyz'])
诚然,这是一个复杂的解决方案,但我几年前提出的方案并没有好多少。希望这有助于澄清正在发生的事情
您真的需要一次调用两个子命令吗argparse
如果可以执行以下操作,则会简单得多:
python function.py -v 1 name1 -d abc xyz foo bar
python function.py -v 1 name2 -i 3 -p abc xyz
换句话说,调用脚本两次。如果对function.py
的每个调用都执行一个独立的自包含操作,那么这很容易实现——两个调用之间的任何连接都体现在共享文件或数据库中。这就是经常使用子命令的方式。试图在一个调用中放入多个子命令并不能节省键入时间。我认为您做错了什么。
首先应该传递位置参数,然后传递关键字参数,例如
python myapp.py arg1 arg2 --kwarg1=1 --kwarg2 val1 --kwarg2 val2
两个问题:一次只能调用一个子parser(作为主脚本的第一个位置参数),即使可以调用多个子parser,也无法判断-d
选项的参数的结束位置。name2
是位置参数还是-d
的参数?name2应该是位置参数。如果这种方法不可行,还有其他方法吗?您可以使用这种解决方法:argparse更灵活;它可以处理混合位置和标记位置。但在本例中,当引入自己的解析约束时,他也使用了subparsers
。@hpaulj我的意思是,在本例中,subparsers是过度杀伤力的。实际上,原始命令是:python function.py-v 1 name1 name2
其中name1,name2是要运行的子模块。现在我希望它们也接受命令行参数。
python myapp.py arg1 arg2 --kwarg1=1 --kwarg2 val1 --kwarg2 val2