Подтвердить что ты не робот

Argparse с требуемыми подкомандами

С python argparse, как сделать подкоманду необходимым аргументом? Я хочу сделать это, потому что я хочу, чтобы argparse выходил из строя, если подкоманда не указана. Вместо этого я переопределяю метод ошибки для печати справки. У меня есть 3-глубокие вложенные подкоманды, поэтому это не вопрос просто обработки нулевых аргументов на верхнем уровне.

В следующем примере, если это так называется, я получаю:

$./simple.py
$

Вместо этого я хочу, чтобы вместо этого argparse сообщал, что требуемая подкоманда не указана:

import argparse

class MyArgumentParser(argparse.ArgumentParser):
    def error(self, message):
        self.print_help(sys.stderr)
        self.exit(0, '%s: error: %s\n' % (self.prog, message))

def main():
    parser = MyArgumentParser(description='Simple example')
    subs = parser.add_subparsers()
    sub_one = subs.add_parser('one', help='does something')
    sub_two = subs.add_parser('two', help='does something else')

    parser.parse_args()

if __name__ == '__main__':
    main()
4b9b3361

Ответ 1

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

http://bugs.python.org/issue9253#msg186387

Там я предлагаю эту работу, устанавливая required атрибут после того, как определены subparsers.

parser = ArgumentParser(prog='test')
subparsers = parser.add_subparsers()
subparsers.required = True
subparsers.dest = 'command'
subparser = subparsers.add_parser("foo", help="run foo")
parser.parse_args()

Обновить

Соответствующий пул-запрос: https://github.com/python/cpython/pull/3027

Ответ 2

В дополнение к hpaulj answer: вы также можете использовать аргумент ключевого слова required с ArgumentParser.add_subparsers() начиная с Python 3.7. Вы также должны передать dest в качестве аргумента. В противном случае вы получите ошибку: TypeError: sequence item 0: expected str instance, NoneType found.

Пример файла example.py:

import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='command', required=True)
foo_parser = subparsers.add_parser("foo", help="command foo")
args = parser.parse_args()

Вывод вызова без аргумента:

$ python example.py
usage: example.py [-h] {foo} ...
example.py: error: the following arguments are required: command

Ответ 3

Как насчет использования required=True? Подробнее здесь.

Ответ 4

Вы можете использовать аргумент dest, который задокументирован в последнем примере в документации для add_subparsers():

# required_subparser.py
import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subparser_name')
one = subparsers.add_parser('one')
two = subparsers.add_parser('two')

args = parser.parse_args()

Запуск с Python 2.7:

$python required_subparser.py 
usage: required_subparser.py [-h] {one,two} ...
required_subparser.py: error: too few arguments
$python required_subparser.py one
$# no error