禁用argparse中的缩写

17

argparse 默认在不会产生歧义的情况下使用缩写。

我不想要缩写,并且想要禁用它。但是在文档中没找到相关信息。

这是否可能?

示例:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--send', action='store_true')
parser.parse_args(['--se']) # returns Namespace(send=True)

但我只想在提供完整参数时才为真,以防止用户错误。

更新:

在Vikas的回答之后,我在Python漏洞跟踪器上创建了一个工单,并且它已经被处理过了。

4个回答

15

从Python 3.5.0开始,您可以通过以下方式初始化ArgumentParser来禁用缩写:

parser = argparse.ArgumentParser(allow_abbrev=False)

另请参见文档


尽管原问题已经超过3年,但这仍然是今天的正确答案。 - jdferreira
1
我选择这个作为正确答案,因为它现在更加恰当。 - juwens

4

Python 2.7 的另一种方式。让我们来看看吧!假设你想要识别没有缩写的 --dog

p = argparse.ArgumentParser()
p.add_argument('--dog')
p.add_argument('--dox', help=argparse.SUPPRESS, metavar='IGNORE')

通过添加第二个参数--dox,该参数仅在第三个字母上与您想要的参数不同,--d--do变得模糊。因此,解析器将拒绝识别它们。您需要添加代码来捕获引发的异常并根据调用parse_args的上下文进行处理。您可能还需要抑制/调整帮助文本。 help=...通过默认帮助消息将该参数保留在选项列表之外(根据此处),而metavar='IGNORE'只是为了明确表明您确实没有对此选项进行任何操作 : )。

@2rs2ts,还有另一个选项供您选择。 - cxw
是的,这对我很有用,因为我甚至无法通过当前的apt存储库访问Python 3.5。谢谢! - 2rs2ts

4
不,显然这是不可能的,至少在Python 2.7.2中是如此。首先,我查看了文档,但没有结果。然后我打开了Lib\argparse.py并仔细阅读了源代码。省略了许多细节后,似乎每个参数都会被解析成类似于这样的正则表达式(argparse:2152):
    # allow one or more arguments
    elif nargs == ONE_OR_MORE:
        nargs_pattern = '(-*A[A-]*)'

这个正则表达式可以成功解析'-'和'--',因此我们无法控制短参数和长参数。其他正则表达式也使用'-*'结构,因此它不依赖于参数类型(没有子参数、1个子参数等)。

在代码的后面,双破折号会被转换为一个破折号(仅适用于非可选参数),同样没有任何用户可控的标志:

    # if this is an optional action, -- is not allowed
    if action.option_strings:
        nargs_pattern = nargs_pattern.replace('-*', '')
        nargs_pattern = nargs_pattern.replace('-', '')

我认为问题与短选项和长选项无关。 - Vikas

4
不行,除非采用丑陋的技巧。
@Vladimir发布的代码片段,我想那不是你要找的。真正实现这个功能的代码如下:
def _get_option_tuples(self, option_string):
    ...
    if option_string.startswith(option_prefix):
    ...

注意看这里,使用的是 startswith 而不是 ==

如果想改变默认行为,你可以扩展 argparse.ArgumentParser 并提供自己的 _get_option_tuples(self, option_string) 方法。我只需要将两个 option_string.startswith(option_prefix) 替换成 option_string == option_prefix, 就成功地实现了自定义。

>>> parser = my_argparse.MyArgparse
>>> parser = my_argparse.MyArgparse()
>>> parser.add_argument('--send', action='store_true')
_StoreTrueAction(option_strings=['--send'], dest='send', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--se'])
usage: [-h] [--send]
: error: unrecognized arguments: --se

注意事项

方法_get_option_tuples_为前缀,这通常意味着在Python中是一个私有方法。覆盖私有方法并不是一个好主意。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接