2016-12-17 4 views
1

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

Пример кода: (test-argparse.py)

#!/usr/bin/env python 

from __future__ import print_function 
import argparse 
import sys 


def main(argv): 
    ap = argparse.ArgumentParser() 
    ap.add_argument("-x", "--foo", metavar="VALUE", default="", 
        help="Test option.") 
    args = ap.parse_args(argv[1:]) 

    print(args.foo) 

if __name__ == "__main__": 
    sys.exit(main(sys.argv)) 

Все мои попытки попробовать пройти "--" в качестве аргумента не в состоянии:

$ test-argparse.py --foo -- 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: argument -x/--foo: expected one argument 

$ test-argparse.py --foo -- -- 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: argument -x/--foo: expected one argument 

$ test-argparse.py --foo=-- 
[] 

$ test-argparse.py --foo=-- -- 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: unrecognized arguments: -- 

$ test-argparse.py --foo="--" 
[] 

$ test-argparse.py '--foo --' 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: unrecognized arguments: --foo -- 

$ test-argparse.py -x-- 
[] 

$ test-argparse.py '-x --' 
-- 

Последний случай ближе, но она включает в себя пространство (и я не могу просто удалить пробелы, потому что, если я хочу разрешить " " в качестве значения?). Есть ли способ, которым я могу это сделать?

Этот аргумент перестановки аргументов на клиентах (что приводит к ненужной двусмысленности) очень расстраивает.

(Я использую Python 2.7.12.)

+0

Я угадываю '--foo =" - "' –

+0

@ cricket_007 Нет. Печатает '[]'. – jamesdlin

+0

В принципе, мне кажется, вам нужны кавычки вокруг вашей строки. Типичные программы bash разделяют параметры и оставшиеся аргументы с тире. –

ответ

2

В идеале --foo=-- должен работать, но текущий синтаксический анализатор удаляет все '-', оставляя пустую строку на своем месте, следовательно, результат foo=[]. Я предложил патч пару лет назад, который должен был зафиксировать это, но он попал в отставание argparse. http://bugs.python.org/issue13922, http://bugs.python.org/issue14364, http://bugs.python.org/issue9571

Python argparse with -- as the value предполагает предварительную обработку sys.argv заменяя один или более -- с чем-то еще.

Если вы играете для исправления файла argparse.py (или подкласса класса ArgumentParser), я могу вернуться к предыдущей работе и предложить исправить ошибку. Хитрость заключается в том, чтобы принять это =--, но по-прежнему использовать первый бесплатный -- в качестве флага «остальные-позиционные» (и сохранить следующие --). К сожалению, один метод, который должен быть исправлен, вложен в гораздо больший.

2

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

Многие, многие программы не принимают -- в качестве аргумента, но они принимают -. Единственная тире - это даже стандартный способ указания «Использовать стандартный ввод или вывод» вместо имени файла.

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

Вы можете использовать -- в качестве позиционного варианта, так что вы, вероятно, можете поддержать это:

--foo -- -- 

Если вы --foo имеют action='store_true' (т.е. это вариант не принимает никаких аргументов), плюс один необязательный позиционный аргумент. Это, вероятно, будет работать, потому что первый -- означает «прекратить обработку тире как опции», а второй - позиционный аргумент.

+0

Я понимаю, что '--' обычно используется for, и я понимаю, почему у argparse есть проблемы (потому что он хочет сделать перестановку аргументов). Я не считаю это оправданием; токен, следующий за опцией, для которой требуется аргумент, должен рассматриваться как аргумент этого параметра. К сожалению, у меня нет выбора разрешить '' - "' как аргумент; аргумент может быть произвольной строкой. – jamesdlin

+0

@jamesdlin: Конечно, вы можете поддержать его как позиционный аргумент. Я добавил что-то в свой ответ, объясняя, как это сделать. –

+0

Извините, не проголосовать за «вероятно, будет работать» ... – martineau

Смежные вопросы