Не удается заставить argparse читать цитированную строку с тире в ней?

Есть ли способ заставить argparse распознавать что-либо между двумя кавычками как один аргумент? Кажется, что он продолжает видеть тире и полагает, что это начало новой опции

У меня есть что-то вроде:

  • Как вставить консоль в окно pyGame?
  • Как расширить класс в python?
  • Разница между абстрактным классом и интерфейсом в Python
  • Являются ли интерфейсы просто «синтаксическим сахаром»?
  • Легкий способ запуска скриптов Python с помощью мыши в OS-X
  • Каков наилучший интерфейс от Python 3.1.1 до R?
  • mainparser = argparse.ArgumentParser() subparsers = mainparser.add_subparsers(dest='subcommand') parser = subparsers.add_parser('queue') parser.add_argument('-env', '--extraEnvVars', type=str, help='String of extra arguments to be passed to model.') ...other arguments added to parser... 

    Но когда я бегу:

     python Application.py queue -env "-s WHATEVER -e COOL STUFF" 

    Это дает мне:

     Application.py queue: error: argument -env/--extraEnvVars: expected one argument 

    Если я останусь с первого тире, он будет работать отлично, но очень важно, чтобы я мог передать строку с тире в ней. Я попытался убежать от него с \, что приводит к его успеху, но добавляет строку \ в строку аргументов. Кто-нибудь знает, как обойти это? Это происходит независимо от того, является или нет аргументом ss в parser.

    EDIT: Я использую Python 2.7.

    EDIT2:

     python Application.py -env " -env" 

    работает отлично, но

     python Application.py -env "-env" 

    не.

    EDIT3: Похоже, это на самом деле ошибка, которая уже обсуждалась: http://www.gossamer-threads.com/lists/python/bugs/89529 , http://python.6.x6.nabble.com/issue9334- argparse-does-not-accept-options-принятие-arguments-begin-with-dash-regression-from-optp-td578790.html . Это всего лишь в 2,7, а не в optparse.

    EDIT4: Текущий отчет об ошибке: http://bugs.python.org/issue9334

  • Parse config files, environment и аргументы командной строки, чтобы получить один набор параметров
  • Каков наилучший интерфейс от Python 3.1.1 до R?
  • Как установить скрипт для работы в любом месте из командной строки?
  • Чтение из файла или STDIN
  • cProfile сохранение данных в файл вызывает перебои символов
  • Легкий способ запуска скриптов Python с помощью мыши в OS-X
  • 3 Solutions collect form web for “Не удается заставить argparse читать цитированную строку с тире в ней?”

    Вы можете запустить аргумент с пробелом python tst.py -e ' -e blah' как очень простой способ обхода. Просто lstrip() возможность вернуть его в нормальное состояние, если хотите.

    Или, если первый «вспомогательный аргумент» также не является допустимым аргументом для исходной функции, вам не нужно ничего делать вообще. То есть единственная причина, по которой python tst.py -e '-s hi -e blah' не работает, заключается в том, что -s является допустимым вариантом для tst.py

    Кроме того, модуль optparse , теперь устаревший, работает без каких-либо проблем.

    Обновленный ответ:

    Вы можете поместить знак равенства, когда вы его назовете:

     python Application.py -env="-env" 

    Оригинальный ответ:

    У меня тоже были проблемы, делающие то, что вы пытаетесь сделать, но в argparse есть метод обхода, который является методом parse_known_args . Это позволит всем аргументам, которые вы не определили, пройти через парсер с предположением, что вы будете использовать их для подпроцесса. Недостатки в том, что вы не получите сообщение об ошибках с плохими аргументами, и вам нужно будет убедиться, что не существует конфликта между вашими параметрами и параметрами вашего подпроцесса.

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

     python Application.py -e "+s WHATEVER +e COOL STUFF" 

    а затем вы переводите «+» в «-» в пост-обработку перед переходом к вашему подпроцессу.

    Эта проблема подробно обсуждается в http://bugs.python.org/issue9334 . Большая часть активности была в 2011 году. Я добавил патч в прошлом году, но есть довольно отставание от патчей argparse .

    Проблема заключается в потенциальной двусмысленности в строке типа '--env' или "-s WHATEVER -e COOL STUFF" когда она следует за опцией, которая принимает аргумент.

    optparse выполняет простой анализ слева направо. Первый --env – это флаг опции, который принимает один аргумент, поэтому он потребляет следующий, независимо от того, как он выглядит. argparse , с другой стороны, дважды перебирает строки. Сначала он классифицирует их как «O» или «A» (флаг или аргумент опций). Во втором цикле они потребляют их, используя сопоставление типа re like для обработки значений переменных nargs . В этом случае похоже, что у нас есть OO , два флага и никаких аргументов.

    Решение при использовании argparse состоит в том, чтобы убедиться, что строка аргумента не будет путаться для флажка параметра. Возможности, которые были показаны здесь (и в проблеме с ошибкой), включают:

     --env="--env" # clearly defines the argument. --env " --env" # other non - character --env "--env " # space after --env "--env one two" # but not '--env "-env one two"' 

    Сам по себе '--env' выглядит как флаг (даже при цитировании, см. sys.argv ), но, если следовать за другими строками, это не так. Но "-env one two" имеет проблемы, потому что он может быть проанализирован как ['-e','nv one two'] , флаг `-e ', за которым следует строка (или даже больше параметров).

    -- и nargs=argparse.PARSER также может использоваться, чтобы заставить argparse просматривать все следующие строки в качестве аргументов. Но они работают только в конце списка аргументов.

    В выпуске 9334 предлагается пакет исправлений для добавления args_default_to_positional=True . В этом режиме анализатор только классифицирует строки как флаги опций, если он может четко соответствовать им с определенными аргументами. Таким образом, «-one» в «–env -one» будет классифицирован как аргумент. Но второй '–env' в '–env –env' по-прежнему будет классифицироваться как флаг опции.


    Расширение соответствующего дела в

    Использование argparse с значениями аргументов, начинающимися с тире («-»)

     parser = argparse.ArgumentParser(prog="PROG") parser.add_argument("-f", "--force", default=False, action="store_true") parser.add_argument("-e", "--extra") args = parser.parse_args() print(args) 

    производит

     1513:~/mypy$ python3 stack16174992.py --extra "--foo one" Namespace(extra='--foo one', force=False) 1513:~/mypy$ python3 stack16174992.py --extra "-foo one" usage: PROG [-h] [-f] [-e EXTRA] PROG: error: argument -e/--extra: expected one argument 1513:~/mypy$ python3 stack16174992.py --extra "-bar one" Namespace(extra='-bar one', force=False) 1514:~/mypy$ python3 stack16174992.py -fe one Namespace(extra='one', force=True) 

    Случай «-foo one» терпит неудачу, потому что -foo интерпретируется как флаг -f плюс неуказанные дополнения. Это то же самое действие, которое позволяет -fe интерпретироваться как ['-f','-e'] .

    Если я изменю nargs на nargs (не PARSER ), все после -e интерпретируется как аргументы для этого флага:

     parser.add_argument("-e", "--extra", nargs=argparse.REMAINDER) 

    Все дела работают. Обратите внимание, что это список. И цитаты не нужны:

     1518:~/mypy$ python3 stack16174992.py --extra "--foo one" Namespace(extra=['--foo one'], force=False) 1519:~/mypy$ python3 stack16174992.py --extra "-foo one" Namespace(extra=['-foo one'], force=False) 1519:~/mypy$ python3 stack16174992.py --extra "-bar one" Namespace(extra=['-bar one'], force=False) 1519:~/mypy$ python3 stack16174992.py -fe one Namespace(extra=['one'], force=True) 1520:~/mypy$ python3 stack16174992.py --extra --foo one Namespace(extra=['--foo', 'one'], force=False) 1521:~/mypy$ python3 stack16174992.py --extra -foo one Namespace(extra=['-foo', 'one'], force=False) 

    argparse.REMAINDER похож на '*', за исключением того, что он принимает все, что следует, независимо от того, выглядит он как флаг или нет. argparse.PARSER больше похож на «+», поскольку он сначала ожидает positional аргумент. Это nargs которые используют subparsers .

    Это использование REMAINDER документировано, https://docs.python.org/3/library/argparse.html#nargs

    Python - лучший язык программирования в мире.