optparse - почему последний символ опции можно игнорировать? С `--file` он ведет себя так же, как`--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, Почему так себя ведет?

2 ответа

Решение

Вы можете увидеть, как работает optparse, открыв optparse.py файл в вашей установке Python.

На окнах это было:

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

Похоже, это задокументировано в этом разделе документации:

opt_str

это строка параметра, видимая в командной строке, которая вызывает обратный вызов. (Если использовалась сокращенная длинная опция, opt_str будет полной, канонической строкой опции - например, если пользователь вводит --foo в командной строке как сокращение для --foobar, тогда opt_str будет "--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 остановится.

optparse будет пытаться сопоставить частичный или более короткий вариант с любыми доступными более длинными именами параметров. Это не особенно хорошо задокументировано, но всегда так и делается. Попытка поиска abbrev в https://docs.python.org/2/library/optparse.html

Многие другие библиотеки разбора опций делают то же самое.

Обратите внимание, что optparse сейчас устарела.

Другие вопросы по тегам