Обзор требований
- использование
argparse
(я буду игнорировать это) - позволяет вызвать одно или два действия (по крайней мере, одно требуется).
- попытаться Pythonic (я бы скорее назвал это "POSIX" -подобным)
Существуют также некоторые неявные требования при работе в командной строке:
- объяснитьиспользование для пользователя удобным для понимания способом
- опции должны быть необязательными
- позволяют задавать флаги, а опции
- позволяют комбинировать с другими параметрами (такими как имя файла или имена).
Пример решения с использованием docopt
(файл managelog.py
):
"""Manage logfiles
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> Password
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
"""
if __name__ == "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
Попробуйте запустить его:
$ python managelog.py
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Показать справку:
$ python managelog.py -h
Manage logfiles
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> P managelog.py [options] upload -- <logfile>...
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
И используйте его:
$ python managelog.py -V -U user -P secret upload -- alfa.log beta.log
{'--': True,
'--pswd': 'secret',
'--user': 'user',
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': False,
'upload': True}
Короткая альтернатива short.py
Может быть еще более короткий вариант:
"""Manage logfiles
Usage:
short.py [options] (process|upload)... -- <logfile>...
short.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> Password
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
"""
if __name__ == "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
Использование выглядит следующим образом:
$ python short.py -V process upload -- alfa.log beta.log
{'--': True,
'--pswd': None,
'--user': None,
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': 1,
'upload': 1}
Обратите внимание, что вместо логических значений для ключей "process" и "upload" есть счетчики.
Оказывается, мы не можем• не допускать дублирования этих слов:
$ python short.py -V process process upload -- alfa.log beta.log
{'--': True,
'--pswd': None,
'--user': None,
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': 2,
'upload': 1}
Выводы
Иногда разработка хорошего интерфейса командной строки может быть сложной задачей.
Существует несколько аспектов программы на основе командной строки:
- хороший дизайн командной строки
- выбор / использование правильного парсера
argparse
предлагает много, но ограничивает возможные сценарии и может стать очень сложным.
С docopt
дела идут намного короче, сохраняя читабельность и предлагая высокую степень гибкости.Если вам удастся получить проанализированные аргументы из словаря и выполнить некоторые преобразования (в целое число, открывающие файлы ..) вручную (или с помощью другой библиотеки, называемой schema
), вы можете найти docopt
подходящую для командыРазбор строки.