Python argparse 可选子参数

发布于 2024-10-21 02:20:10 字数 1012 浏览 2 评论 0原文

我希望我的程序有一个参数,其中包含一些必需参数和一些可选参数。像这样的东西:

[--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 会抛出异常。

I'd like to have an argument to my program that has some required parameters along with some optional parameters. Something like this:

[--print text [color [size]]

so you could pass it any of these:

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

There could be multiple of these so it has to be a single add_argument. For example:

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

I can achieve arguments that are close to what I want:

>>> 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 ...]]

but not quite. Is there any way to do this with argparse? I know I could make them all nargs="*" but then --help would not list the names of the optional arguments. If I pass nargs="*" and a tuple for metavar, argparse throws an exception.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我不会写诗 2024-10-28 02:20:10

怎么样

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')

How about

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)

Then you get something like this:

$ ./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')
无远思近则忧 2024-10-28 02:20:10

阅读源代码(从take_action),我相信你想要的是不可能的。所有参数解析和传递给操作都是基于 nargs 完成的,nargs 可以是数字、OPTIONAL ("?")、ZERO_OR_MORE ("*")、ONE_OR_MORE(“+”)、PARSERREMAINDER。这必须在 Action 对象(处理输入)看到它正在获取的内容之前确定,因此它无法动态地找出 nargs。

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

Reading the source code (start in take_action), I believe what you want is impossible. All argument parsing and passing to actions is done based on nargs, and nargs is either a number, OPTIONAL ("?"), ZERO_OR_MORE ("*"), ONE_OR_MORE ("+"), PARSER, or REMAINDER. This must be determined before the Action object (which handles the input) even sees what it's getting, so it can't dynamically figure out nargs.

I think you'll need to live with a workaround. I would maybe have --foo-x x, --foo-y y, and --foo-z z, and perhaps also --foo x y z.

浮华 2024-10-28 02:20:10

这适用于单个参数:

parser.add_argument('--write_google', nargs='?', const='Yes',
                    choices=['force', 'Yes'],
                    help="write local changes to google")

that will work for single arg:

parser.add_argument('--write_google', nargs='?', const='Yes',
                    choices=['force', 'Yes'],
                    help="write local changes to google")
勿挽旧人 2024-10-28 02:20:10

根据 Devin Jeanpierre 的回答,似乎使用“+”(一个或多个)而不是“*”可以实现您想要实现的目标。
(PS:如果我有足够的积分,我会在他的回答中发表评论)

According to Devin Jeanpierre's answer, it seems that using '+' (one or more) instead of '*' would do what you are trying to achieve.
(PS: I would've just commented in his answer if I had enough points)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文