默认子命令,或使用 argparse 处理无子命令
我如何拥有默认的 子命令,或处理使用 argparse
未给出子命令的情况?
import argparse
a = argparse.ArgumentParser()
b = a.add_subparsers()
b.add_parser('hi')
a.parse_args()
在这里,我希望选择一个命令,或者仅根据下一个最高级别的解析器(在本例中为顶级解析器)来处理参数。
joiner@X:~/src> python3 default_subcommand.py usage: default_subcommand.py [-h] {hi} ... default_subcommand.py: error: too few arguments
How can I have a default sub-command, or handle the case where no sub-command is given using argparse
?
import argparse
a = argparse.ArgumentParser()
b = a.add_subparsers()
b.add_parser('hi')
a.parse_args()
Here I'd like a command to be selected, or the arguments to be handled based only on the next highest level of parser (in this case the top-level parser).
joiner@X:~/src> python3 default_subcommand.py usage: default_subcommand.py [-h] {hi} ... default_subcommand.py: error: too few arguments
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
在 Python 3.2(和 2.7)上,您会收到该错误,但在 3.3 和 3.4 上则不会(无响应)。因此,在 3.3/3.4 上,您可以测试
parsed_args
是否为空的Namespace
。更通用的解决方案是添加方法
set_default_subparser()
(取自 ruamel. std.argparse 包)并在parse_args()
之前调用该方法:这适用于 2.6(如果
argparse
是从 PyPI 安装)、2.7、3.2、3.3、3.4。并允许您同时执行和
并获得相同的效果。
允许选择一个新的默认子解析器,而不是现有的子解析器。
代码的第一个版本允许将先前定义的子解析器之一设置为默认子解析器。以下修改允许添加一个新的默认子解析器,然后可以使用它来专门处理用户未选择子解析器的情况(代码中标记的不同行)
“默认”选项仍然不会显示在帮助中:
但是,现在可以区分并单独处理调用提供的子解析器之一,以及在未提供参数时调用默认子解析器:
On Python 3.2 (and 2.7) you will get that error, but not on 3.3 and 3.4 (no response). Therefore on 3.3/3.4 you could test for
parsed_args
to be an emptyNamespace
.A more general solution is to add a method
set_default_subparser()
(taken from the ruamel.std.argparse package) and call that method just beforeparse_args()
:This will work with 2.6 (if
argparse
is installed from PyPI), 2.7, 3.2, 3.3, 3.4. And allows you to do bothand
with the same effect.
Allowing to chose a new subparser for default, instead of one of the existing ones.
The first version of the code allows setting one of the previously-defined subparsers as a default one. The following modification allows adding a new default subparser, which could then be used to specifically process the case when no subparser was selected by user (different lines marked in the code)
The "default" option will still not show up in the help:
However, it is now possible to differentiate between and separately handle calling one of the provided subparsers, and calling the default subparser when no argument was provided:
看来我最终自己偶然发现了解决方案。
如果该命令是可选的,则这使得该命令成为一个选项。在我原来的解析器配置中,我有一个 package 命令,它可以执行一系列可能的步骤,或者如果没有给出任何步骤,它将执行所有步骤。这使得该步骤成为一个选择:
It seems I've stumbled on the solution eventually myself.
If the command is optional, then this makes the command an option. In my original parser configuration, I had a
package
command that could take a range of possible steps, or it would perform all steps if none was given. This makes the step a choice:这是添加
set_default_subparser
方法的更好方法:Here's a nicer way of adding a
set_default_subparser
method:您可以在主解析器上复制特定子解析器的默认操作,从而有效地将其设为默认操作。
不适用于
add_subparsers(required=True)
,这就是if args.func
位于此处的原因。You can duplicate the default action of a specific subparser on the main parser, effectively making it the default.
Does not work with
add_subparsers(required=True)
, which is why theif args.func
is down there.也许您正在寻找的是
add_subparsers
的dest
参数:(警告:适用于 Python 3.4,但不适用于 2.7)
现在您可以只使用
cmd
的值:Maybe what you're looking for is the
dest
argument ofadd_subparsers
:(Warning: works in Python 3.4, but not in 2.7)
Now you can just use the value of
cmd
:就我而言,我发现当
argv
为空时,向parse_args()
显式提供子命令名称是最简单的。运行示例:
In my case I found it easiest to explicitly provide the subcommand name to
parse_args()
whenargv
was empty.Example runs:
这是另一个使用辅助函数来构建已知子命令列表的解决方案:
Here's another solution using a helper function to build a list of known subcommands:
在 python 2.7 中,您可以覆盖子类中的错误行为(遗憾的是没有更好的方法来区分错误):
In python 2.7, you can override the error behaviour in a subclass (a shame there isn't a nicer way to differentiate the error):
我相信您可以添加一个带有默认值的参数,当没有设置任何内容时将使用该默认值。
请参阅:http://docs.python.org/dev/library/argparse。 html#default
编辑:
抱歉,我读你的问题有点快。
我不认为你可以通过 argparse 直接做你想做的事情。但是你可以检查 sys.argv 的长度,如果它的长度为 1 (仅脚本名称),那么你可以手动传递默认参数进行解析,执行如下操作:
我认为这应该做你想要的,但我同意如果能开箱即用就好了。
You can add an argument with a default value that will be used when nothing is set I believe.
See this: http://docs.python.org/dev/library/argparse.html#default
Edit:
Sorry, I read your question a bit fast.
I do not think you would have a direct way of doing what you want via argparse. But you could check the length of sys.argv and if its length is 1 (only script name) then you could manually pass the default parameters for parsing, doing something like this:
I think that should do what you want, but I agree it would be nice to have this out of the box.
供以后参考:
所以,这两个将是相同的:
For later reference:
so, these two will be same: