Распечатать справку, если нет позиционного аргумента? - PullRequest
1 голос
/ 17 января 2012

Я делаю довольно простой скрипт, который принимает следующие параметры:

-p --port integer, optional, default 5050
-f --fork boolean, optional, default False
action string, required, needs to be either start or stop

Я пытался реализовать это в argparse, но это не вывод справки, когда строка действия не указана, просто сбой всех безобразных:

usage: __init__.py [-h] [-p PORT] [-f] {start,stop}
__init__.py: error: argument action: invalid choice: '__init__.py' (choose from 'start', 'stop')

Даже когда я передаю «старт» или «стоп», он не работает с тем же сообщением. Вот мой код:

parser = argparse.ArgumentParser(description="Start or stop the server.",
    epilog="If you don't know what you're doing, run. Run for your life.\n")
parser.add_argument("-p", "--port", type=int, nargs=1, default=5050,
    dest="port", help="The port to run the server on.")
parser.add_argument("-f", "--fork", action="store_true", default=False,
    dest="fork", help="Fork to background? Default is false.")
parser.add_argument("action", type=str, choices=("start","stop"), help="Whether to 'start' or 'stop' the server.")

Что я здесь не так делаю? Надеюсь, мои намерения довольно понятны из моего кода.

Ответы [ 2 ]

2 голосов
/ 17 января 2012

Если указаны недопустимые аргументы, модуль argparse предназначен для печати сообщения об использовании и описания проблемы, а затем выхода, что в точности и происходит в вашем примере.

Если вы хотите, чтобы вместо этого вы печатали справочное сообщение, вам нужно разобраться с этим делом самостоятельно.Например, этот код напечатает сообщение справки, если не будет выполнено никаких действий:

parser = argparse.ArgumentParser(description="Start or stop the server.",
    epilog="If you don't know what you're doing, run. Run for your life.\n",
    prog="myserver")
parser.add_argument("-p", "--port", type=int, nargs=1, default=5050,
    dest="port", help="The port to run the server on.")
parser.add_argument("-f", "--fork", action="store_true", default=False,
    dest="fork", help="Fork to background? Default is false.")
parser.add_argument("action", nargs="?", type=str, choices=("start","stop"),
    help="Whether to 'start' or 'stop' the server.")

args = parser.parse_args()
if args.action is None:
    parser.print_help()
    sys.exit(1)

Если я запустил это без действий, я получу:

$ python s.py
usage: myserver [-h] [-p PORT] [-f] [{start,stop}]

Start or stop the server.

positional arguments:
  {start,stop}          Whether to 'start' or 'stop' the server.

optional arguments:
  -h, --help            show this help message and exit
  -p PORT, --port PORT  The port to run the server on.
  -f, --fork            Fork to background? Default is false.

If you don't know what you're doing, run. Run for your life.

Однако,если я запускаю это с недопустимым действием или недопустимым аргументом, то он возвращается к предполагаемому поведению модуля argparse:

 $ python s.py not_valid
usage: myserver [-h] [-p PORT] [-f] [{start,stop}]
myserver: error: argument action: invalid choice: 'not_valid' (choose from 'start', 'stop')
1 голос
/ 17 января 2012

Какую версию Python вы используете?Когда я запускаю ваш код с 2.7.1, он работает нормально.

$ ./t stop
$ ./t start
$ ./t -f start
$ ./t -f stop
$ ./t -f
usage: someprog [-h] [-p PORT] [-f] {start,stop}
someprog: error: too few arguments
$ ./t -f -p 8080
usage: someprog [-h] [-p PORT] [-f] {start,stop}
someprog: error: too few arguments
$ ./t -f -p 8080 start

Один совет: если вы укажете «prog» в ctor, вы можете переопределить его, используя init .py в качествеимя файла

parser = argparse.ArgumentParser(
    prog="someprog",
    description="Start or stop the server.",
    epilog="If you don't know what you're doing, run. Run for your life.\n"
)

Кроме того, - это использование печати, но не долгая помощь. Вы можете сделать что-то подобное, чтобы сделать вещи немного более очевидными ..

try:
    parser.parse_args()
except Exception e:
    print "************************"
    parser.print_help()
    print "************************"
...