Как анализировать позиционные аргументы с помощью знака минус (отрицательные числа) с помощью argparse
Я хотел бы проанализировать требуемый позиционный аргумент, содержащий список целых чисел, разделенных запятыми. Если первое целое число содержит знак минус ('-'), argparse жалуется:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('positional')
parser.add_argument('-t', '--test', action='store_true')
opts = parser.parse_args()
print opts
$ python example.py --test 1,2,3,4
Namespace(positional='1,2,3,4', test=True)
$ python example.py --test -1,2,3,4
usage: example.py [-h] [-t] positional
example.py: error: too few arguments
$ python example.py --test "-1,2,3,4"
usage: example.py [-h] [-t] positional
example.py: error: too few arguments
Я видел, что люди предлагают использовать какой-то другой символ, кроме -
, как символ флага, но я бы предпочел не делать этого. Есть ли другой способ настроить argparse, чтобы позволить как --test
, так и -1,2,3,4
в качестве допустимых аргументов?
Ответы
Ответ 1
Вам нужно вставить --
в аргументы командной строки:
$ python example.py --test -- -1,2,3,4
Namespace(positional='-1,2,3,4', test=True)
Двойная тире останавливает argparse, ища любые дополнительные опции; это стандартный метод defacto для обработки именно этого прецедента для инструментов командной строки.
Ответ 2
В документации :
Метод parse_args() пытается выдавать ошибки всякий раз, когда пользователь имеет явно допустил ошибку, но некоторые ситуации по своей сути неоднозначны. Например, аргумент командной строки -1 может быть либо попыткой указать опцию или попытку предоставить позиционный аргумент. Метод parse_args() здесь осторожен: позиционные аргументы могут начните только с - если они выглядят как отрицательные числа, и нет параметры в парсере, которые выглядят как отрицательные числа:
Так как -1,2,3,4
не выглядит как отрицательное число, вы должны "убежать" от него с помощью --
, как в большинстве систем * nix.
Другим решением было бы использовать nargs
для позиционирования и передавать числа в виде пробела:
#test.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('positional', nargs='*') #'+' for one or more numbers
print parser.parse_args()
Вывод:
$ python test.py -1 2 3 -4 5 6
Namespace(positional=['-1', '2', '3', '-4', '5', '6'])
Третий способ получить то, что вы хотите, это использовать parse_known_args
вместо parse_args
.
Вы не добавляете позиционный аргумент в синтаксический анализатор и не анализируете его вручную:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--test', action='store_true')
parsed, args = parser.parse_known_args()
print parsed
print args
Результат:
$ python test.py --test -1,2,3,4
Namespace(test=True)
['-1,2,3,4']
Это имеет тот недостаток, что текст справки будет менее информативным.