Python argparse:至少需要一个参数
我一直在使用 argparse
作为一个可以 -process
、-upload
或两者兼有的 Python 程序:
parser = argparse.ArgumentParser(description='Log archiver arguments.')
parser.add_argument('-process', action='store_true')
parser.add_argument('-upload', action='store_true')
args = parser.parse_args()
如果没有至少一个参数,该程序就毫无意义。如何配置 argparse 来强制选择至少一个参数?
更新:
按照评论:用至少一个选项参数化程序的 Pythonic 方法是什么?
I've been using argparse
for a Python program that can -process
, -upload
or both:
parser = argparse.ArgumentParser(description='Log archiver arguments.')
parser.add_argument('-process', action='store_true')
parser.add_argument('-upload', action='store_true')
args = parser.parse_args()
The program is meaningless without at least one parameter. How can I configure argparse
to force at least one parameter to be chosen?
UPDATE:
Following the comments: What's the Pythonic way to parametrize a program with at least one option?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
我知道这已经很古老了,但是需要一个选项但禁止多个选项(XOR)的方法是这样的:
输出:
I know this is old as dirt, but the way to require one option but forbid more than one (XOR) is like this:
Output:
如果不是“或两者”部分(我最初错过了这一点),你可以使用这样的东西:
不过,使用 子命令 代替。
If not the 'or both' part (I have initially missed this) you could use something like this:
Though, probably it would be a better idea to use subcommands instead.
需求审查
在命令行中也有一些隐含的要求:
使用
docopt
的示例解决方案(文件managelog.py
):尝试运行它:
显示帮助:
并使用它:
简短的替代方案
short.py
还可以有更短的变体:
用法如下所示:
注意,“process”和“upload”键不是布尔值,而是计数器。
事实证明,我们无法避免重复这些词:
结论
设计良好的命令行界面有时可能具有挑战性。
基于命令行的程序有多个方面:
argparse
的命令行的良好设计提供了很多,但限制了可能的场景并且可能变得非常复杂。
使用
docopt
,事情会变得更短,同时保持可读性并提供高度的灵活性。如果您设法从字典中获取解析后的参数,并手动(或通过其他名为schema
),您可能会发现docopt
非常适合命令行解析。Requirements Review
argparse
(I will ignore this one)There are also some implicit requirements when living on command line:
Sample solution using
docopt
(filemanagelog.py
):Try to run it:
Show the help:
And use it:
Short alternative
short.py
There can be even shorter variant:
Usage looks like this:
Note, that instead of boolean values for "process" and "upload" keys there are counters.
It turns out, we cannot prevent duplication of these words:
Conclusions
Designing good command line interface can be challenging sometime.
There are multiple aspects of command line based program:
argparse
offers a lot, but restricts possible scenarios and can become very complex.With
docopt
things go much shorter while preserving readability and offering high degree of flexibility. If you manage getting parsed arguments from dictionary and do some of conversions (to integer, opening files..) manually (or by other library calledschema
), you may finddocopt
good fit for command line parsing.对于http://bugs.python.org/issue11588,我正在探索概括
mutually_exclusive_group的方法
概念来处理这样的情况。通过此开发
argparse.py
,https://github .com/hpaulj/argparse_issues/blob/nested/argparse.py我可以写:
它会产生以下
help
:这接受像 '-u'、'-up'、'--proc --up' 等输入。
它最终会运行类似的测试到 https://stackoverflow.com/a/6723066/901925,尽管错误消息需要更清晰:
我想知道:
参数
kind='any', required=True
是否足够清晰(接受任意一组;至少需要一个)?用法
(-p | -u)
清楚吗?所需的mutual_exclusive_group 会产生相同的结果。是否有一些替代符号?使用这样的组比
phihag 的
简单测试更直观吗?For http://bugs.python.org/issue11588 I am exploring ways of generalizing the
mutually_exclusive_group
concept to handle cases like this.With this development
argparse.py
, https://github.com/hpaulj/argparse_issues/blob/nested/argparse.pyI am able to write:
which produces the following
help
:This accepts inputs like '-u', '-up', '--proc --up' etc.
It ends up running a test similar to https://stackoverflow.com/a/6723066/901925, though the error message needs to be clearer:
I wonder:
are the parameters
kind='any', required=True
clear enough (accept any of the group; at least one is required)?is usage
(-p | -u)
clear? A required mutually_exclusive_group produces the same thing. Is there some alternative notation?is using a group like this more intuitive than
phihag's
simple test?最好的方法是使用 python 内置模块 add_mutually_exclusive_group。
如果您只想通过命令行选择一个参数,只需使用 required=True 作为组的参数
The best way to do this is by using python inbuilt module add_mutually_exclusive_group.
If you want only one argument to be selected by command line just use required=True as an argument for group
这达到了目的,并且这也将反映在 argparse 自动生成的
--help
输出中,恕我直言,这是大多数理智的程序员想要的(也适用于可选参数):关于此的官方文档:
https://docs.python.org/3/library/argparse.html#选择
This achieves the purpose and this will also be reflected in the argparse autogenerated
--help
output, which is IMHO what most sane programmers want (also works with optional arguments):Official documentation on this:
https://docs.python.org/3/library/argparse.html#choices
如果您需要 python 程序至少使用一个参数运行,请添加一个不具有选项前缀(默认为 - 或 --)的参数,并设置
nargs=+(至少需要一个参数)。我发现这个方法的问题是,如果不指定参数,argparse 将生成“参数太少”错误,并且不会打印出帮助菜单。如果您不需要该功能,请按以下方式在代码中执行此操作:
我认为当您添加带有选项前缀的参数时,nargs 控制整个参数解析器而不仅仅是选项。 (我的意思是,如果您有一个带有
nargs="+"
的--option
标志,那么--option
标志至少需要如果您有option
和nargs="+"
,则它至少需要一个参数。)If you require a python program to run with at least one parameter, add an argument that doesn't have the option prefix (- or -- by default) and set
nargs=+
(Minimum of one argument required). The problem with this method I found is that if you do not specify the argument, argparse will generate a "too few arguments" error and not print out the help menu. If you don't need that functionality, here's how to do it in code:I think that when you add an argument with the option prefixes, nargs governs the entire argument parser and not just the option. (What I mean is, if you have an
--option
flag withnargs="+"
, then--option
flag expects at least one argument. If you haveoption
withnargs="+"
, it expects at least one argument overall.)也许使用子解析器?
现在
--help
显示:您也可以向这些子解析器添加其他选项。此外,您还可以绑定要在给定子命令上直接调用的函数,而不是使用
dest='subparser_name'
(请参阅文档)。Maybe use sub-parsers?
Now
--help
shows:You can add additional options to these sub-parsers as well. Also instead of using that
dest='subparser_name'
you can also bind functions to be directly called on given sub-command (see docs).对于像这样的情况
我们可以使用以下
For cases like
We can use the following
对操作列表使用append_const,然后检查该列表是否已填充:
您甚至可以直接在常量中指定方法。
Use append_const to a list of actions and then check that the list is populated:
You can even specify the methods directly within the constants.
使用
Maybe try:
至少这是我刚刚使用的;希望这对将来的人有帮助!
Using
Maybe try:
At least this is what I just used; hopefully this helps someone in the future!