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
сейчас устарела.