Argparse:获取在命令行中传递的所有选项

时间:2015-02-10 15:24:42

标签: python python-2.7 argparse

我在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中找到它的等价物

2 个答案:

答案 0 :(得分:4)

只测试默认值集,例如默认默认值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:]已经告诉你的内容相呼应,当然。

答案 1 :(得分:0)

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

parse_args会跟踪变量seen_actions中看到的选项。它使用此集来测试是否已经看到所有“必需”选项。对此集合进行了细化,seen_non_default_actions用于测试所需的互斥组。

parse_args以外的这些集合都不可用。我已经开发了一个扩展互斥组概念的补丁。这将提供一个可以在这些seen集上运行测试的钩子(在bug报告中查找标题中包含'nest inclusive groups'的一个)。