【问题标题】:Python 3 argparse: Conditional argument only required if optional argument not provided?Python 3 argparse:仅在未提供可选参数时才需要条件参数?
【发布时间】:2016-07-02 22:30:30
【问题描述】:

[Python 3/argparse]

假设我的应用需要一个位置参数:

myApp.py [desired_function]

但是,如果用户提供了某个选项,那么desired_function 应该不是必需的。

myApp.py --list-functions

在这种情况下,如果 --list-functions 被传递,我希望应用程序继续运行,将我设置的变量 desired_function 保留为空,因为我的代码将看到用户传递了 --list-functions 并采取相应的行动。

但是,如果用户提供--list-functions 选项,那么参数解析器应该会产生错误,因为用户没有提供所需的位置参数。

如果用户没有提供可选参数,我如何让 argparsedesired_function 位置设为必需?

到目前为止我的代码:

parser = argparse.ArgumentParser(description="test app")
parser.add_argument("desired_function", help="The function desired", action="store", default="", dest="func")
parser.add_argument("--list-functions",help="List the available functions", action="store_true", default=False, dest="list_mode")

在这种状态下,调用 myApp.py --list-functions 将失败并显示:

usage: myApp.py [-h] [--list-functions] desired_function
myApp.py: error: the following arguments are required: desired_function

【问题讨论】:

  • --list-functions 简单地产生help 输出是否有意义,所以--list-functions 使用action='help' 并等效于-h,然后将函数列表合并到@987654337 @ 输出?或者,为desired_function 提供choices,让argparse 完成显示它们的工作?

标签: python-3.x argparse


【解决方案1】:

这是一个简单的解析器,它使位置参数可选(nargs=?)。

In [171]: parser=argparse.ArgumentParser()
In [172]: parser.add_argument('func', nargs='?',default='foo')
In [173]: parser.add_argument('--list',action='store_true')
In [174]: args=parser.parse_args(['--list'])
In [175]: args
Out[175]: Namespace(func='foo', list=True)
In [176]: args=parser.parse_args(['bar'])
In [177]: args
Out[177]: Namespace(func='bar', list=False)
In [178]: parser.parse_args(['--list','bar'])
Out[178]: Namespace(func='bar', list=True)
In [179]: parser.parse_args([])
Out[179]: Namespace(func='foo', list=False)

不要给位置参数一个dest 参数;它已经在第一个字符串中获得了一个。 store_true 动作不需要默认值;它会自动获得False

通过此设置,您可以查看args.list;它True,然后忽略args.func 值。如果False,请使用args.func。如果你给func 一个有意义的默认值,那么用户是否给你一个值都无关紧要。换句话说,它确实不是必需的。 (如果需要,定义默认值是没有意义的)。或者,如果他们两个都给你,你可以反对:

In [184]: args=parser.parse_args(['--list','bar'])
In [185]: if args.list and args.func!='foo':
       parser.error('you stupid user ...')
   .....:     
usage: ipython3 [-h] [--list] [func]
ipython3: error: you stupid user ...

我们可以更进一步,将这两个参数放在mutually_exclusive_group 中,并将该组设为required。这样的组接受一个像这样的可选位置。我认为文档很清楚,但如果需要,我可以扩展我的答案。

【讨论】:

  • 这仍然只允许一个位置参数吗?即如果我出于某种原因想在它之后添加另一个参数,nargs="?" 会干扰吗?假设示例:myApp.py processSomethingFromFile theFileToProcess.dat 我将文件名作为第二个位置参数。另外,即使我没有做这样的事情,传递多个位置参数仍然应该是一个错误......?
  • 尝试不同的组合。这样做比冗长的解释更容易看到。
  • 你可以有多个位置。但是,如果有不止一种分配参数的方法,那么制作多个“可选”(?+*) 可能会很棘手。互斥分组只允许一个位置。
猜你喜欢
  • 2014-10-26
  • 2020-11-05
  • 2020-08-24
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
相关资源
最近更新 更多