Попробовал библиотеку @asolovyov для разбора аргументов командной строки в
Python, которая называется opster (вот доки, исходники). Это ещё
одна библиотека, решающая те же задачи, что и стандартные getopt
, optparse
и
argparse
.
Впечатления приятные. Кода действительно надо писать меньше. Самая главная идея — отделить код обработки опций от кода функции, которой они нужны как аргументы. То есть если у меня есть функция:
def test(arg1, arg2, include=[], exclude=[], verbose=False):
'''A test command.'''
...
то для превращения её в утилиту командной строки мне не надо её менять, только
снабдить декоратором @command
или обернуть её в этот декоратор непосредственно
в main
:
@command(usage='%name [hIXv] arg1 arg2',
options=[
('I', 'include', [], 'include names'),
('X', 'exclude', [], 'exclude names'),
('v', 'verbose', False, 'be more verbose')])
def test(arg1, arg2, include=[], exclude=[], verbose=False):
'''A test command.'''
...
Получилось 5 строк. Этот же пример на getopt
занимает где-то 30 строк.
Затем можно вызвать функцию, передав аргументы командной строки:
if __name__ == '__main__':
test(argv=sys.argv[1:])
либо вызывать как обычную функцию:
test('foo', 'bar', include=['path1', 'path2'], verbose=True)
При этом у программы появится автоматическая справка по -h
:
$ ./test -h
test [hIXv] arg1 arg2
A test command.
options:
-I --include include names
-X --exclude exclude names
-v --verbose be more verbose
-h --help show help
Ещё несколько слов об особенностях. Есть поддержка подкоманд (в духе Mercurial,
Git). Нет обязательных опций, но это даже хорошо. Какой смысл в обязательных
опциях? Есть поддержка задания одной опции несколько раз (значений типа
[str]
), а также значений bool
, str
, int
и интересных значений str ->
a
, то есть функций по преобразованию значения во что угодно.
Из минусов можно назвать не всегда корректную работу с Unicode, stack trace при указании неверных значений опций вместо красивых сообщений об ошибках, невозможность задать только короткое имя опции и ещё несколько мелочей.
Библиотека opster
определённо заслуживает внимания.
См. также: