使用 argparse 的有序和重复标志

Posted

技术标签:

【中文标题】使用 argparse 的有序和重复标志【英文标题】:Ordered and repeated flags using argparse 【发布时间】:2020-12-14 07:29:10 【问题描述】:

如果可能,尝试使用 argparse 实现 CLI,而不编写我自己的解析器。基本上我想使用命令行在程序中按顺序调用不同的方法,即:

my_program.py --doA --doB --doA --doA

我已经看到了关于如何获取有序参数的好主意的线程,但我想我最终会得到一个像 ['doA', 'doB', 'doA', 'doB'] 这样的列表,我仍然需要自己解析参数。

有没有办法利用 argparse 中的工具来帮助按顺序执行这些命令?谢谢!

【问题讨论】:

argparse 不适合这种解析。 【参考方案1】:

这是一个解析器,它会按顺序重复收集这些参数:

In [1]: import argparse                                                         
In [2]: parser = argparse.ArgumentParser()                                      
In [3]: parser.add_argument('--doA', dest='cmd', const='doA', action='append_con
   ...: st');                                                                   
In [4]: parser.add_argument('--doB', dest='cmd', const='doB', action='append_con
   ...: st');                                                                   

测试:

In [5]: args = parser.parse_args('--doA --doB --doA --doA'.split())             
In [6]: print(args)                                                             
Namespace(cmd=['doA', 'doB', 'doA', 'doA'])

做点什么:

In [7]: for action in args.cmd: 
   ...:     print('action:', action) 
   ...:                                                                         
action: doA
action: doB
action: doA
action: doA

如果我已经定义:

def doA(*args):
   # do something
   pass

并使用const=doA,那么args.cmd 列表将是

Namespace(cmd=[doA, doB, ...])

我们可以写

for action in args.cmd:
    action(arguments)

argparse docs 有类似这样的子解析和set_default 命令。

如果这些是您接受的唯一论点,那将是过度杀戮。但如果有其他需要argparse 的选项,这将适合。但接受一个

parser.add_argument('--cmd', nargs='*', ...)

会好的。它可以使用choices 来限制输入字符串,甚至可以使用type 函数将字符串转换为函数对象。

【讨论】:

【参考方案2】:

命令行参数可以分为 3 组:

    选项 - 以 --- 为前缀,通常指定命令的行为方式 (--verbose),可能会或可能不会接受值,通常顺序无关紧要 子命令 - 是少数程序定义的关键字之一,告诉程序执行程序全套功能的某个子集(pull in git pull),通常一次只能指定一个李> 参数 - 通常在命令末尾传递的值,并指定要在执行期间使用的值,并且通常这些值被简单地使用而无需任何修改

大多数参数解析器将选项视为无序的,并且倾向于简单地为命名空间中的变量或属性设置值以供程序员使用。如果不编写自定义解析器,这使得有序选项通常是不可能的。

对于您的工具,您只想指定要执行的操作的有序列表,因此将它们作为值传递给选项或简单参数可能更有意义。

my_program.py --actions doA doB doC doD
my_program.py doA doB doC doD

Argparsers(如 python 的 argparse)不会改变赋予选项的值或作为参数传递的值,这意味着将保留操作的顺序。

【讨论】:

以上是关于使用 argparse 的有序和重复标志的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在没有任何标志的情况下使用 argparse?

如何有一个特定的子命令需要带有 argparse 的标志?

Python Argparse:使用单个大头钉作为标志,例如`./myscript -5` 像 Git 和 CoreUtils

Python Argparse:使用空标志

为啥 argparse 不能正确解析我的布尔标志? [复制]

argparse:在 --help 中的标志后删除空格并使用 colorama 为帮助输出着色