0

我想在​​内提出一些与我的程序主要功能有关的参数。但是,我有两个问题: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') 
+1

没有内置argparse。你只需自己写逻辑 –

+0

谢谢你的简洁明确的答案。 – GH05T

回答

4

​​内部只有两个分组工具。相互排斥的组和子分析器。 MEG的所有动作都是xor。虽然可能需要组本身,但其所有操作必须是可选的。大多数必须被标记(可选),但可能是一个'可选'的位置(是的,术语可能会混淆)。

没有嵌套组规定,也没有规定其他逻辑(和,或任何,不等)。那些已经被要求了,我已经开始了一个补丁,但是它并没有接近完成。其实测试本身并不难;以一种清晰的方式定义组是非常困难的,正如显示使用情况一样。一旦允许嵌套,并尝试考虑所有逻辑可能性,额外代码的数量将大幅增加。

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

这里有一个内部变量'seen_actions',可以很好地用于这个测试,但是我还没有想出一个简单的方法来让像你这样的程序员可以使用它。我对扩展组的最初想法是创建一个钩子,它允许您在解析结束时通过访问此变量来运行您自己的函数。

看一下前面的答案吧。


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


我还想问的人,你会如何表达你的usage线分组中(S)?它的要求很难在usage中表达,它们很难在​​中实施。

+0

我不介意自己做逻辑。我正要做一次重大的改革,现在应该回顾一下我是否可以用'argparse'实现我的目标。感谢您的回复(即使大部分内容超出了我的理解:)我仍然有一个明确的答案)。 – GH05T

+0

如果我重新访问问题并提出更具体的修复方法,我会在评论中通知您。 – hpaulj

相关问题