Отображать справочное сообщение с python argparse, когда script вызывается без каких-либо аргументов
Это может быть просто. Предположим, у меня есть программа, которая использует argparse для обработки аргументов/параметров командной строки. Следующее выведет сообщение "help":
./myprogram -h
или
./myprogram --help
Но если я запускаю script без каких-либо аргументов, он ничего не делает. Я хочу, чтобы он отображал сообщение об использовании, когда оно вызывается без аргументов. Как это делается?
Ответы
Ответ 1
Этот ответ приходит от Стивена Бетарда из групп 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()
печатает в стандартный вывод по умолчанию. Как init_js предлагает, используйте parser.print_help(sys.stderr)
для печати в stderr.
Ответ 2
Вместо того, чтобы писать класс, вместо него можно использовать try/except
try:
options = parser.parse_args()
except:
parser.print_help()
sys.exit(0)
Поверхность заключается в том, что рабочий процесс более ясен, и вам не нужен класс заглушки. Недостатком является то, что первая строка "использования" печатается дважды.
Для этого потребуется хотя бы один обязательный аргумент. Без обязательных аргументов допустимость нулевого аргумента в командной строке действительна.
Ответ 3
С помощью 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)
Ответ 4
Если у вас есть аргументы, которые должны быть указаны для запуска script, используйте параметр требуемый для ArgumentParser, как показано ниже: -
parser.add_argument('--foo', required=True)
parse_args() сообщит об ошибке, если script запущен без каких-либо аргументов.
Ответ 5
Если вы связываете функции по умолчанию для (под) синтаксических анализаторов, как указано в разделе add_subparsers
, вы можете просто добавить их в качестве действия по умолчанию:
parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)
Добавьте попытку - за исключением случаев, когда вы вызываете исключения из-за отсутствия позиционных аргументов.
Ответ 6
Бросив мою версию в кучу:
import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
parser.print_help()
parser.exit(1)
Вы можете заметить parser.exit
- я в основном делаю это так, потому что он сохраняет строку импорта, если это единственная причина для sys
в файле...
Ответ 7
Самым чистым решением будет передача аргумента по умолчанию вручную, если в командной строке не было указано ни одного:
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))
Это напечатает полную справку (не короткое использование), если вызвано без аргументов.
Ответ 8
Есть пара однострочников с 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])
Ответ 9
parser.print_help()
parser.exit()
Метод parser.exit
также принимает значение status
(returncode) и значение message
(включая конечную новую строку!).
упрямый пример,
:)
#!/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 $?
usage: helloworld.py [-h] [--example]
Example argparser based python file
optional arguments:
-h, --help show this help message and exit
--example Example Argument
I just don't know what went wrong, maybe missing --example condition?
128
$ python3 ~/helloworld.py --example; echo $?
0
Ответ 10
Задайте свои позиционные аргументы с помощью nargs и проверьте, пусты ли позиционные args.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='?')
args = parser.parse_args()
if not args.file:
parser.print_help()
Ссылка Python nargs
Ответ 11
Вот еще один способ сделать это, если вам нужно что-то гибкое, когда вы хотите отобразить справку, если переданы определенные параметры, ни одного вообще или более 1 конфликтующего аргумента:
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 ...
Ура!
Ответ 12
Если в вашей команде пользователю нужно выбрать какое-либо действие, используйте взаимоисключающую группу с required = True.
Это своего рода расширение ответа, данного 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
usage: a_test.py [-h] (--batch pay_id | --list | --all)
a_test.py: error: one of the arguments --batch --list --all is required
Это только дать основную помощь. И некоторые другие ответы окажут вам полную помощь. Но по крайней мере ваши пользователи знают, что они могут делать -h
Ответ 13
вы можете использовать optparse
from optparse import OptionParser, make_option
parser = OptionParser()
parser.add_option('--var',
help='put the help of the commandline argument')
(options, args) = parser.parse_args()
./myprogram --help
will print all the help messages for each given argument.