13

我想为我的程序提供一个参数,其中包含一些必需参数和一些可选参数。像这样的东西:

[--print text [color [size]]

所以你可以通过其中任何一个:

mycommand --print hello
mycommand --print hello blue
mycommand --print hello red 12

可能有多个,所以它必须是一个 add_argument。例如:

[--print text [color]] [--output filename [overwrite]]

我可以实现接近我想要的论点:

>>> parser = argparse.ArgumentParser()
>>> act = parser.add_argument('--foo', nargs=3, metavar=('x','y','z'))
>>> act = parser.add_argument('--bar', nargs='?')
>>> act = parser.add_argument('--baz', nargs='*')
>>> parser.print_help()
usage: [-h] [--foo x y z] [--bar [BAR]] [--baz [BAZ [BAZ ...]]]

optional arguments:
  -h, --help            show this help message and exit
  --foo x y z
  --bar [BAR]
  --baz [BAZ [BAZ ...]]

但不完全。有没有办法用 argparse 做到这一点?我知道我可以全部制作它们nargs="*",但 --help 不会列出可选参数的名称。如果我传递nargs="*"一个元组元组,argparse 会引发异常。

4

4 回答 4

9

怎么样

def printText(args):
  print args

parser = argparse.ArgumentParser()
subparser = parser.add_subparsers()
printer = subparser.add_parser('print')
printer.add_argument('text')
printer.add_argument('color', nargs='?')
printer.add_argument('size', type=int, nargs='?')
printer.set_defaults(func=printText)

cmd = parser.parse_args()
cmd.func(cmd)

然后你会得到这样的东西:

$ ./test.py -h
usage: test.py [-h] {print} ...

positional arguments:
  {print}

$ ./test.py print -h
usage: test.py print [-h] text [color] [size]

positional arguments:
  text
  color
  size

$ ./test.py print text
Namespace(color=None, func=<function printText at 0x2a96150b90>, size=None, text='text')

$ ./test.py print text red
Namespace(color='red', func=<function printText at 0x2a96150b90>, size=None, text='text')

$ ./test.py print text red 12
Namespace(color='red', func=<function printText at 0x2a96150b90>, size=12, text='text')
于 2011-12-14T10:39:04.413 回答
7

阅读源代码(从 开始take_action),相信你想要的都是不可能的。所有参数解析和传递给动作都是基于 nargs 完成的,并且 nargs 是一个数字、OPTIONAL("?")、ZERO_OR_MORE("*")、ONE_OR_MORE("+") PARSER、 或REMAINDER。这必须在 Action 对象(处理输入)甚至看到它得到什么之前确定,所以它不能动态地找出nargs.

我认为你需要接受一种解决方法。我可能会有--foo-x x, --foo-y y, and --foo-z z, 也许还有--foo x y z.

于 2011-03-10T09:17:53.653 回答
1

根据 Devin Jeanpierre 的回答,似乎使用 '+' (一个或多个)而不是 '*' 会达到你想要达到的效果。(PS:如果我有足够的分数,我会在他的回答中发表评论)

于 2017-08-22T15:54:14.227 回答
0

这将适用于单个 arg:

parser.add_argument('--write_google', nargs='?', const='Yes',
                    choices=['force', 'Yes'],
                    help="write local changes to google")
于 2013-04-26T14:15:04.300 回答