Показать справочное сообщение с помощью python argparse, когда сценарий вызывается без аргументов

StackOverflow https://stackoverflow.com/questions/4042452

  •  27-09-2019
  •  | 
  •  

Вопрос

Это может быть простой. Предположим, у меня есть программа, которая использует ArgParse для обработки аргументов / опций / опций. Следующее будет распечатать сообщение «HELP»:

./myprogram -h

или:

./myprogram --help

Но, если я запускаю сценарий без каких-либо аргументов, вообще ничего не делают. Что я хочу, чтобы отобразить сообщение об использовании, когда он называется без аргументов. Как это сделано?

Это было полезно?

Решение

Этот ответ поступает из Стивена Биттарда на групп Google. Отказ Я репостемся здесь, чтобы упростить людей без учетной записи Google для доступа.

Вы можете переопределить поведение по умолчанию error Метод:

import argparse
import sys

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)

parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()

Обратите внимание, что вышеуказанное решение будет распечатать сообщение справки всякий раз, когда errorметод срабатывает. Например, test.py --blah будет распечатать сообщение о помощи тоже, если --blah не допустимый вариант.

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

import argparse
import sys

parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)
args=parser.parse_args()

Обратите внимание, что parser.print_help() Отпечатывает stdout по умолчанию. Так как init_js предлагает, использовать parser.print_help(sys.stderr) печатать на Стдерр.

Другие советы

Вместо того, чтобы написать класс, вместо этого можно использовать попробую / кроме

try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)

Увеличивается, что рабочий процесс более понятен, и вам не нужен класс заглушки. Недостатком является то, что первая линия «Использование» напечатана дважды.

Это потребуется хотя бы один обязательный аргумент. Без обязательных аргументов, предоставляя нулевые аргументы на командную строку действительны.

С argparse вы можете сделать:

parser.argparse.ArgumentParser()
#parser.add_args here

#sys.argv includes a list of elements starting with the program
if len(sys.argv) < 2:
    parser.print_usage()
    sys.exit(1)

Если у вас есть аргументы, которые должны быть указаны для скрипта для запуска - используйте требуется Параметр для аргументов Parser, как показано ниже: -

parser.add_argument('--foo', required=True)

PARSE_ARGS () сообщит об ошибке, если сценарий работает без каких-либо аргументов.

Если вы связываете функции по умолчанию для (SUB) парсеров, как упоминается под add_subparsers, вы можете просто добавить его как действие по умолчанию:

parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)

Добавьте попытки, если вы поднимаете исключения из-за отсутствия позиционных аргументов.

Бросая мою версию в кучу здесь:

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
    parser.print_help()
    parser.exit(1)

Вы можете заметить parser.exit - в основном я так делаю это, потому что это экономит импортную линию, если это была единственная причина для sys В файл ...

Самое чистое решение будет вручную пройти аргумент по умолчанию, если ни один не был приведен в командной строке:

parser.parse_args(args=None if sys.argv[1:] else ['--help'])

Полный пример:

import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost', help='Host to connect to')
# parse arguments
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])

# use your args
print("connecting to {}".format(args.host))

Это будет печатать полную справку (не краткое использование), если они называются аргументами W / O.

Есть пара одноклассников с sys.argv[1:] (Очень распространенный идиома Python для обозначения аргументов командной строки, будучи sys.argv[0] Имя сценария), которое может сделать работу.

Первый самоуверенно, чистый и питон:

args = parser.parse_args(None if sys.argv[1:] else ['-h'])

Второй маленький хакер. Объединение ранее оцениваемого факта, что пустой список False с True == 1 а также False == 0 Эквивалентности вы получаете это:

args = parser.parse_args([None, ['-h']][not sys.argv[1:]])

Возможно, слишком много скобок, но довольно ясно, если был сделан предыдущий выбор аргумента.

_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
parser.print_help()
parser.exit()

То parser.exit Метод также принимает status (returnCode) и A message Значение (включить трейлинг Newline самостоятельно!).

Неужелированный пример :)

#!/usr/bin/env python3

""" Example argparser based python file
"""

import argparse

ARGP = argparse.ArgumentParser(
    description=__doc__,
    formatter_class=argparse.RawTextHelpFormatter,
)
ARGP.add_argument('--example', action='store_true', help='Example Argument')


def main(argp=None):
    if argp is None:
        argp = ARGP.parse_args()  # pragma: no cover

    if 'soemthing_went_wrong' and not argp.example:
        ARGP.print_help()
        ARGP.exit(status=128, message="\nI just don't know what went wrong, maybe missing --example condition?\n")


if __name__ == '__main__':
    main()  # pragma: no cover

Пример звонков:

$ python3 ~ / helloworld.py; echo $? Использование: helloworld.py [-H] [--Example] Пример ARGParser на основе Python файл Python необязательные аргументы: -H, --help Показать эту справку сообщение и выйти - например, пример аргумента я просто не знаю, что пошло не так, может быть Отсутствует - описательное состояние? 128 $ python3 ~ / helloworld.py --example; echo $? 0.

Установите свои позиционные аргументы с NARGS и проверьте, будут ли позиционные аргументы пустыми.

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='?')
args = parser.parse_args()
if not args.file:
    parser.print_help()

Ссылка Python Nargs.

Вот еще один способ сделать это, если вам нужно что-то гибкое, где вы хотите отобразить справку, если определенные параметры пройдены, нет вообще или более 1 конфликтующих ARG:

import argparse
import sys

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--days', required=False,  help="Check mapped inventory that is x days old", default=None)
    parser.add_argument('-e', '--event', required=False, action="store", dest="event_id",
                        help="Check mapped inventory for a specific event", default=None)
    parser.add_argument('-b', '--broker', required=False, action="store", dest="broker_id",
                        help="Check mapped inventory for a broker", default=None)
    parser.add_argument('-k', '--keyword', required=False, action="store", dest="event_keyword",
                        help="Check mapped inventory for a specific event keyword", default=None)
    parser.add_argument('-p', '--product', required=False, action="store", dest="product_id",
                        help="Check mapped inventory for a specific product", default=None)
    parser.add_argument('-m', '--metadata', required=False, action="store", dest="metadata",
                        help="Check mapped inventory for specific metadata, good for debugging past tix", default=None)
    parser.add_argument('-u', '--update', required=False, action="store_true", dest="make_updates",
                        help="Update the event for a product if there is a difference, default No", default=False)
    args = parser.parse_args()

    days = args.days
    event_id = args.event_id
    broker_id = args.broker_id
    event_keyword = args.event_keyword
    product_id = args.product_id
    metadata = args.metadata
    make_updates = args.make_updates

    no_change_counter = 0
    change_counter = 0

    req_arg = bool(days) + bool(event_id) + bool(broker_id) + bool(product_id) + bool(event_keyword) + bool(metadata)
    if not req_arg:
        print("Need to specify days, broker id, event id, event keyword or past tickets full metadata")
        parser.print_help()
        sys.exit()
    elif req_arg != 1:
        print("More than one option specified. Need to specify only one required option")
        parser.print_help()
        sys.exit()

    # Processing logic here ...

Ваше здоровье!

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

Это своего рода расширение к ответу, данному PD321.

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--batch", action='store', type=int,  metavar='pay_id')
group.add_argument("--list", action='store_true')
group.add_argument("--all", action='store_true', help='check all payments')

args=parser.parse_args()

if args.batch:
    print('batch {}'.format(args.batch))

if args.list:
    print('list')

if args.all:
    print('all')

Выход:

$ python3 a_test.py.
Использование: a_test.py [-h] (- datch pay_id | --list | --all)
a_test.py: Ошибка: один из аргументов --batch --list - все требуется

Это только дают основную помощь. И некоторые другие ответы дадут вам полную помощь. Но, по крайней мере, ваши пользователи знают, что могут сделать -час

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top