argparse:模拟 GCC 的“-fno-<option>”语义

argparse: Emulating GCC's "-fno-<option>" semantics

GCC 命令行解析的一个很好的特性是大多数“-fmy-option”形式的标志都有一个名为“-fno-my-option”的否定版本。最右边的出现优先,因此您可以将“-fno-my-option”附加到您的 CFLAGS 或 Makefile 中的类似内容以禁用选项而不破坏其他标志。

我想在包装脚本为 Python 并使用 argparse 的工具中支持类似的东西。仅使用 store_true 操作定义参数的两个版本的明显黑客行不通,因为这不会让我要求最正确的出现。

显然,支持像 --my-option=yes / --my-option=no 这样的语法很容易,但如果用户不必传递参数就好了。

有没有办法让 argparse 有一个像这样的布尔标志的 on/off 开关?

无需花哨的脚下功夫,我可以设置一对写入相同 dest 的参数,并利用最后写入的那个这一事实:

In [765]: parser=argparse.ArgumentParser()
In [766]: a1=parser.add_argument('-y',action='store_true')
In [767]: a2=parser.add_argument('-n',action='store_false')

没有 dest 参数,它们使用从选项字符串派生的名称。但是我可以给出一个 dest,或者在创建后更改该值:

In [768]: a1.dest
Out[768]: 'y'
In [769]: a2.dest
Out[769]: 'n'
In [770]: a1.dest='switch'
In [771]: a2.dest='switch'

现在使用任何一个都将设置 switch 属性。

In [772]: parser.parse_args([])
Out[772]: Namespace(switch=False)

默认值来自第一个定义的参数。这是在解析开始时如何设置默认值的函数。对于所有其他输入,它是设置值的最后一个参数

In [773]: parser.parse_args(['-y'])
Out[773]: Namespace(switch=True)
In [774]: parser.parse_args(['-n'])
Out[774]: Namespace(switch=False)
In [775]: parser.parse_args(['-n','-y','-n','-y'])
Out[775]: Namespace(switch=True)
In [776]: parser.parse_args(['-n','-y','-n'])
Out[776]: Namespace(switch=False)

也可以使用单独的命令设置默认值:

parser.set_defaults(switch='foo')

如果您想经常使用此类功能,您可以编写一个小实用函数来创建带有您想要的任何标志和目标的参数对。甚至有人 bug/issues 请求这样的增强功能,但我怀疑它是否会实现。