【问题标题】:Argparse: get all options passed in command lineargparse:获取命令行中传递的所有选项
【发布时间】:2015-02-11 01:28:47
【问题描述】:

我在 python 中使用 Argparse 库,需要检索在调用时传递的所有选项。例如,如果给定程序需要三个命令行参数:

parser.add_argument('-a', action="store_true", default=False)
parser.add_argument('-b', action="store", dest="b")
parser.add_argument('-c', action="store", dest="c", type=int)

所以如果我打电话给python test.py -b 我需要一种方法来知道 -b 是作为命令行选项传递的。

在旧的 optparse 中,这可以通过覆盖 optparse.Option 来完成,但我无法在 argparse 中找到它的等价物

【问题讨论】:

  • 有效吗?如果没有,会发生什么?
  • 我不明白你想要实现什么,以及为什么 argparse 没有做你需要的。能不能给个详细的解释?
  • 你有输出的例子吗?
  • 详细说明您可以在optparse 中做什么。

标签: python python-2.7 argparse


【解决方案1】:

只测试默认值集,比如default默认值None:

if args.b is None:
    # -b was not used

这不适用于-a,因为store_true 意味着默认False。你可以告诉argparse 使用None 作为默认值:

parser.add_argument('-a', action="store_true", default=None)

但由于您不能使用-a 并且not args.a 为真,您仍然可以测试那个默认值:

parser.add_argument('-a', action="store_true")
args = parser.parse_args()
if not args.a:
    # -a was not used

如果None 是一个有效的选择(例如,您使用action="store_const", const=None),则使用不同的哨兵作为默认值:

_sentinel = object()
parser.add_argument('-d', action="store_const",
                    const=None, default=_sentinel)
args = parser.parse_args()
if args.d is _sentinel():
    # -d was not used

您还可以通过将默认值设置为argparse.SUPPRESS 来防止设置默认值全部

parser.add_argument('-e', default=argparse.SUPPRESS)
args = parser.parse_args()
if not hasattr(args, 'e'):
    # -e was not used

您可以通过循环parser._optionals._actions 并查看它们的.dest 属性是否存在并且未设置为.default 值来列出实际使用的所有可选操作:

used_options = [
    action for action in parser._optionals._actions
    if getattr(args, action.dest, action.default) is not action.default]

演示:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-a', action="store_true", default=False)
_StoreTrueAction(option_strings=['-a'], dest='a', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('-b', action="store", dest="b")
_StoreAction(option_strings=['-b'], dest='b', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('-c', action="store", dest="c", type=int)
_StoreAction(option_strings=['-c'], dest='c', nargs=None, const=None, default=None, type=<type 'int'>, choices=None, help=None, metavar=None)
>>> def list_used_options(parser, args):
...     return [
...         action for action in parser._optionals._actions
...         if getattr(args, action.dest, action.default) is not action.default]
... 
>>> args = parser.parse_args(['-a'])
>>> list_used_options(parser, args)
[_StoreTrueAction(option_strings=['-a'], dest='a', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)]

这只是与sys.argv[1:] 已经告诉你的内容相呼应,当然。

【讨论】:

  • 我需要将传递给命令行的所有参数存储在一个列表中。可用选项很长,每个选项都没有与之关联的默认值。如果你能帮助我,将不胜感激
  • @ujjwalwahi:传递给脚本的所有命令行选项都已作为sys.argv 中的列表提供。
  • @JoelCornett:不知何故,我认为这还不够好。拥有 Action 实例可以有其用途,但如果 OP 想要确切的命令行,那么它确实已经存在。
【解决方案2】:

检查默认值是检查是否已给出(看到)选项的最直接方法。默认的None 在这方面很好,因为你不能在命令行中给出None。对于store_true(或false),默认值始终是相反的布尔值。但是,我意识到使用这样的默认值并不总是方便(或可能?)。

parse_args 确实在变量seen_actions 中跟踪看到的选项。它使用此集合来测试是否已看到所有“必需”选项。对此集合的改进,seen_non_default_actions 用于测试所需的互斥组。

但这些集合在parse_args 之外均不可用。我已经开发了一个扩展互斥组概念的补丁。这将提供一个钩子,可以在这些 seen 集合上运行测试(在错误报告中查找标题中带有“嵌套包含组”的集合)。

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 2020-01-16
    • 2018-11-29
    • 2023-03-13
    • 2011-06-02
    • 2015-09-14
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多