optparse - 为什么可以忽略选项的最后一个字符?使用 `--file` 它的行为与 `--fil` 相同

optparse - why the last char of the option can be ignored? With `--file` it behaves same as `--fil`

这是一个简单的代码示例:

from optparse import OptionParser

parser = OptionParser()
parser.add_option("-f", "--file", dest="filename")

(options, args) = parser.parse_args()
print options

我已将其保存到文件中 运行。有效:

$ python script.py --file some_name
{'filename': 'some_name'}

但这是诀窍:

$ python script.py --fil some_name
{'filename': 'some_name'}

它也适用于未声明的选项 fil。 为什么会这样?

optparse 将尝试将部分或较短的选项与任何可用的较长选项名称进行匹配。它没有特别详细的记录,但它总是这样做。尝试在 https://docs.python.org/2/library/optparse.html#how-callbacks-are-called

中搜索 abbrev

许多其他选项解析库也是这样做的。

请注意 optparse 现已弃用。

您可以通过打开 python 安装中的 optparse.py 文件来查看 optparse 的工作原理。

在 windows 这是:

C:\Python27\Lib\optparse.py

_match_abbrev 函数在第 1675 行:

def _match_abbrev(s, wordmap):
    """_match_abbrev(s : string, wordmap : {string : Option}) -> string

    Return the string key in 'wordmap' for which 's' is an unambiguous
    abbreviation.  If 's' is found to be ambiguous or doesn't match any of
    'words', raise BadOptionError.
    """
    # Is there an exact match?
    if s in wordmap:
        return s
    else:
        # Isolate all words with s as a prefix.
        possibilities = [word for word in wordmap.keys()
                         if word.startswith(s)]
        # No exact match, so there had better be just one possibility.
        if len(possibilities) == 1:
            return possibilities[0]
        elif not possibilities:
            raise BadOptionError(s)
        else:
            # More than one possible completion: ambiguous prefix.
            possibilities.sort()
            raise AmbiguousOptionError(s, possibilities)

_match_long_opt 调用,由 _process_long_opt

调用

这似乎记录在文档的 this 部分:

opt_str

is the option string seen on the command-line that’s triggering the callback. (If an abbreviated long option was used, opt_str will be the full, canonical option string—e.g. if the user puts --foo on the command-line as an abbreviation for --foobar, then opt_str will be "--foobar".)

如果我们将您提供的示例更改为:

from optparse import OptionParser

parser = OptionParser()
parser.disable_interspersed_args()
parser.add_option("-f", "--file", dest="filename")
parser.add_option("-z", "--film", dest="filmname")

(options, args) = parser.parse_args()
print options

使用--fil的测试用例,你得到一个错误:

error: ambiguous option: --fil (--file, --film?)

所以可以使用较短的名称,但如果有任何歧义,optparse 将停止。