Поиск позиционного параметра Argparse

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

    self.parser = ArgumentParser(description=program_license,
                     formatter_class=RawDescriptionHelpFormatter,
                     conflict_handler='resolve')
    self.parser.add_argument('-V', '--version',
                     action='version',
                     version=program_version_message)
    self.parser.add_argument('--logfile', action='store',
                     dest='logfile', default='daddyvision.log')
    self.parser.add_argument('prog', help=SUPPRESS, nargs=1)
    self.parser.add_argument('library', metavar="library", nargs='*')

    group_loglvl = self.parser.add_mutually_exclusive_group()
    group_loglvl.add_argument("--verbose", dest="loglevel",
                     action="store_const", const="VERBOSE",
                     default='INFO')
    group_loglvl.add_argument("--debug", dest="loglevel",
                     action="store_const", const="DEBUG")
    group_loglvl.add_argument("--trace", dest="loglevel",
                     action="store_const", const="TRACE")
    group_loglvl.add_argument("--quiet", dest="loglevel",
                     action="store_const", const="WARNING")
    group_loglvl.add_argument("--errors", dest="loglevel",
                     action="store_const", const="ERROR")

    args = self.parser.parse_args(arg)

если моя командная строка: pgm --error имя файла, я получаю «ошибка: нераспознанные аргументы: имя файла»

если моя строка cmd - имя файла pgm --error, она работает без ошибок.

Что я делаю не так. Все, что я читал, наводит меня на мысль, что позиционное положение может быть первым или последним. Среда Python 2.7.

Если я делаю позиционные требования (nargs='+'), это работает, но параметр не является обязательным.


person user1110844    schedule 16.08.2013    source источник
comment
Это может оказаться полезным: github.com/docopt/docopt   -  person Blender    schedule 16.08.2013


Ответы (1)


Ваш код будет легче протестировать, если вы очистите его, удалив такие элементы, как self. Мне нравится делать import argparse, а затем вставлять остальные и получать работающий пример.

Как вы это тестируете?

parser.parse_args('pgm --error filename'.split())

or

parser.parse_args('--error filename'.split())

parser.parse_args() анализирует sys.argv[1:]. Если бы я запустил скрипт с именем pgm с этим аргументом, я бы ожидал, что он проанализирует --error filename.

Справка, без ПОДАВЛЕНИЯ это:

usage: ipython [-h] [-V] [--logfile LOGFILE]
               [--verbose | --debug | --trace | --quiet | --errors]
               prog [library [library ...]]

positional arguments:
  prog
  library

optional arguments:
  -h, --help         show this help message and exit
  ...
  --errors

Несмотря на это, ключом к вашей ошибке является prog [library [library ...]] часть usage.

Что происходит с pgm --error filename, так это то, что строка pgm устанавливает как prog='pgm', так и library=[]. С * (или ?) library удовлетворяется вообще отсутствием строки. После этого ему некуда поместить строку filename.

pgm filename --error дает library=['filename']. --error pgm filename тоже должно работать.

Проблема не в том, что посты должны быть первыми (или последними), а в том, что они должны быть вместе (если 2-й — «?» или «*»).

Этот отчет об ошибке пытается объяснить это взаимодействие позиционных и необязательных значений '*'.

http://bugs.python.org/issue14191#msg185517


Если pgm — это имя программы sys.argv[0], то оно вам не нужно в argparse. Удалите аргумент prog, и ваша проблема исчезнет (тогда будет только одна позиция).

person hpaulj    schedule 17.08.2013
comment
Когда я передаю sys.argv() без записи pgm, я получаю sys.argv[0] как первую запись в списке для библиотеки. - person user1110844; 16.09.2013
comment
sys.argv() выдает ошибку. Если вы хотите передать sys.argv в parse_args, используйте sys.argv[1:], то есть все, кроме sys.argv[0]. - person hpaulj; 16.09.2013