Обзор требований
- использовать
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}
Обратите внимание, что вместо логических значений для ключей "процесс" и "загрузка" используются счетчики.
Оказывается, мы не можем предотвратить дублирование этих слов:
$ 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
подходящий вариант для синтаксического анализа командной строки.
-x
всегда является флагом и необязателен. Отрежьте,-
если это необходимо.