【问题标题】:Argparse Mutually exclusive groups not working on pair of positional and optional argumentsArgparse 互斥组不适用于一对位置和可选参数
【发布时间】:2019-02-16 08:08:05
【问题描述】:

我已经编写了一个代码,我希望输入文件作为命令行参数。我希望用户以两种方式提供:

  1. 使用标志 --input,例如:

    python3 prog.py --input A.cpp

  2. 没有任何标志

    python3 prog.py A.cpp

两者应该是一样的。

我使用 argparse 为它编写了一个程序。

#!/usr/bin/env python3
import argparse
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    input_file = parser.add_mutually_exclusive_group()
    input_file.add_argument('inp',nargs='?',help='file name')
    input_file.add_argument('--input',dest='inp',help='file name')
    args = parser.parse_args()
    print(args)

它适用于:

$ python3 prog.py A.cpp
Namespace(inp='A.cpp')

虽然不是:

$ python3 prog.py --input A.cpp
Namespace(inp=None)

我希望这两种方式是互斥的,并且它们的价值可以保存到目的地(就像我在这里做的inp)。一个人可以跳过两者。表示它们不是必需的。

我怎样才能实现它?

【问题讨论】:

  • 那是一个糟糕的 CLI。选择其中一种方式即可,不要一厢情愿。
  • 你能不能给我一些其他的建议。我认为它对用户很友好,因为我的程序的早期版本不支持标志,所以用户习惯了 python3 prog.py A.cpp ,我想在不删除旧方式的情况下添加对 argparse 的支持
  • 您是否尝试先定义标记的参数?或者使用相同的dest 可能是问题所在。位置的默认值可能会覆盖可选的值。我不认为mutual_exclusive 组有问题。但我必须运行一些测试用例才能确定。
  • 是的,我通过在代码中切换两行的位置来尝试这两种组合

标签: python-3.x command-line-arguments argparse


【解决方案1】:

问题在于常见的dest。位置的默认值是覆盖可选的值。

In [13]: p = argparse.ArgumentParser()
In [14]: a1 = p.add_argument('--foo')
In [15]: a2 = p.add_argument('bar', nargs='?', default='default')

In [16]: p.parse_args('xxx'.split())
Out[16]: Namespace(bar='xxx', foo=None)

In [17]: p.parse_args('--foo 1'.split())
Out[17]: Namespace(bar='default', foo='1')

更改以便他们共享dest

In [18]: a1.dest = 'bar'

先解析可选项,然后解析位置。因为是'?',所以默认值放在命名空间中,覆盖之前的值

In [19]: p.parse_args('--foo 1'.split())
Out[19]: Namespace(bar='default')

这里可选的值覆盖了位置的值:

In [20]: p.parse_args('xxx --foo 1'.split())
Out[20]: Namespace(bar='1')

这里显式的位置值覆盖了可选项:

In [21]: p.parse_args('--foo 1 xxx'.split())
Out[21]: Namespace(bar='xxx')

我意识到差异很微妙。它与位置和可选项的解析方式(交替)有关,还与 nargs='?' 位置的处理方式有关。

【讨论】:

  • 我同意你提到的一切。它正在按原样工作。但我的疑问在于mutually_exclusive_groups。至少不应该有这样的overriding 问题,因为这两个选项都完全是mutually exclusive 所以不能一次发生,那么他们必须更小心地处理它。
  • 我对@9​​87654332@ 很好,因为它们不是相互排斥的,解析器可能会认为它可能是人没有提供价值,所以给它default value 但这不应该是mutually exclusive 中的情况是 persion 已将值提供给 --input 很确定没有 inp 的机会,因此不应为其赋予默认值,WDYT @hpaulj
  • 您正在设想一种更复杂的互斥机制。它所测试的只是您的用户是否为组中的多个操作提供了输入。 argparse 中没有任何内容检查两个或多个操作是否写入同一个 dest 或协调此类写入。
  • 我会将dest 分开,并使用解析后测试将它们组合起来。这个逻辑应该很简单。
  • 我解决了这个问题,我只是想必须有一些already provided 方法来处理这种情况。我认为应该有一个。编写自己的逻辑是 OK 对我来说,但如果 argparse 为我工作会很酷。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
  • 2013-03-29
  • 2016-05-24
  • 2020-07-29
  • 2016-05-04
  • 2011-05-27
相关资源
最近更新 更多