argparse:如何要求一组不是互斥的参数,也不是全部可选的参数?



我正在尝试对argparse中所需的程序的主要功能进行某些论证。 但是,我有两个问题:

  1. 并非所有参数都是相互排斥的。
  2. 即使它们都是相互排斥、相互排斥的群体 要求参数是可选的,并且主函数search(不是必需的)使用位置参数。

理想情况下,我认为'search'是主要功能。 因此,我希望它的论点是立场性的;尽管不需要search但是,至少需要满足以下条件之一:search, --name, --list, --add, --import, --encrypt, --decrypt, --delete-database, --rename-database, --backup

此外,--name不是一个相互排斥的选项,它是多用途的:

如果它
  • 由自身调用,则将创建其参数(数据库的名称)(如果它尚不存在)。
  • 如果(数据库)确实存在,则将其用作调用它的任何其他选项函数的参数:例如,-n myfirstdb --decrypt
  • 然而,如果--name不存在,我假设最近访问的数据库。

目前,我必须运行一个开始变得繁琐的检查,以查看是否已调用任何主要选项,同时测试是否存在--name

最后,显然,相互排斥的选项不能一起使用。

如何让search成为这个必需的互斥组的一部分? 我怎样才能--name也成为这个必需的群体之一,但又不能相互排斥其中任何一个?

我正在试验子解析器,但我不确定它们是否是我问题的解决方案。 任何建议都可能会为我节省几天的反复试验,非常感谢。

parser.add_argument(
'search', nargs='*', type=str, metavar='S', help='search [field] for string(s)')
parser.add_argument(
'--name', '-n', type=str, help='name of the database; created if does not exist')
main_ex_group = parser.add_argument_group(
title='main functions').add_mutually_exclusive_group()
main_ex_group.add_argument(
'--list', '-l', action='store_true', help='list databases')
main_ex_group.add_argument(
'--add', '-a', action='store_true', help='add new record to database')
main_ex_group.add_argument(
'--import','-i', dest='include', metavar='PATH', type=str,
help='import file(s) at PATH')
main_ex_group.add_argument(
'--encrypt', action='store_true', help='encrypt database')
main_ex_group.add_argument(
'--decrypt', action='store_true', help='decrypt database')
main_ex_group.add_argument(
'--delete-database', metavar='NAME', type=str,
help='delete a database')
main_ex_group.add_argument(
'--rename-database', nargs=2, metavar='NAME', type=str,
help='rename a database')
main_ex_group.add_argument(
'--backup', nargs=2, metavar='NAME DEST', type=str,
help='copy database to destination')

import_group = parser.add_argument_group(title='options for import')
import_group.add_argument(
'--parse-fields', action='store_true',
help='extract keys/fields from included file(s); used as columns')
import_group.add_argument(
'--delimiter', metavar='S', default='::', help='key-value separator')

argparse中内置了两个分组工具。 互斥组和子分析器。 MEG 的所有操作都xor。 虽然组本身可能是必需的,但其所有操作都必须是可选的。大多数必须被标记(可选),但其中一个可能是"可选"位置(是的,术语可能会令人困惑)。

没有为嵌套组提供,也没有为其他逻辑(和,或,任何,不是等)提供。 这些已经被要求,我已经在一个补丁上工作,但它还没有完成。 实际上测试本身并不难;以清晰的方式定义组更难,显示用法也是如此。 一旦你允许嵌套,并尝试考虑所有逻辑可能性,额外代码的数量就会大幅增长。

目前,最好的选择是在解析完成后进行自己的测试。 只要您使用合理的默认值(例如默认默认值None),就不难。

有一个内部变量"seen_actions"非常适合用于此测试,但我还没有找到一种简单的方法来将其提供给像您这样的程序员。 我扩展组的最初想法是创建一个钩子,让你在解析结束时运行自己的函数,并访问这个变量。

查看侧栏中的早期答案。


argument group是一种显示工具 - 它对帮助行进行分组。 您可以在参数组中嵌套互斥组。这有效地为 MEG 提供了标题/描述,并一起显示其参数。但这不会影响usage或测试。 以另一种方式嵌套是没有意义的。 嵌套在 MEG 中的 MEG 也是可能的,但最终效果是将所有操作放在一个更大的组中 - 并弄乱使用(请参阅最近的 Python 错误/问题)。 存在的嵌套与其说是设计,不如说是类继承的特征。


我还想问人们,你会如何在usage行中表达你的分组? 它的要求很难用usage表达,很难用argparse实现。

相关内容

最新更新