TL; DR
Используйте nargs
опцию или 'append'
настройку action
опции (в зависимости от того, как вы хотите, чтобы пользовательский интерфейс вел себя).
nargs
parser.add_argument('-l','--list', nargs='+', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 2345 3456 4567
nargs='+'
принимает 1 или более аргументов, nargs='*'
принимает ноль или более.
Append
parser.add_argument('-l','--list', action='append', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 -l 2345 -l 3456 -l 4567
С append
вы можете несколько раз создать список.
Не используйте type=list
!!! - Там, наверное , не ситуация , в которой вы хотели бы использовать type=list
с argparse
. Когда-либо.
Давайте более подробно рассмотрим некоторые из возможных способов сделать это и конечный результат.
import argparse
parser = argparse.ArgumentParser()
# By default it will fail with multiple arguments.
parser.add_argument('--default')
# Telling the type to be a list will also fail for multiple arguments,
# but give incorrect results for a single argument.
parser.add_argument('--list-type', type=list)
# This will allow you to provide multiple arguments, but you will get
# a list of lists which is not desired.
parser.add_argument('--list-type-nargs', type=list, nargs='+')
# This is the correct way to handle accepting multiple arguments.
# '+' == 1 or more.
# '*' == 0 or more.
# '?' == 0 or 1.
# An int is an explicit number of arguments to accept.
parser.add_argument('--nargs', nargs='+')
# To make the input integers
parser.add_argument('--nargs-int-type', nargs='+', type=int)
# An alternate way to accept multiple inputs, but you must
# provide the flag once per input. Of course, you can use
# type=int here if you want.
parser.add_argument('--append-action', action='append')
# To show the results of the given option to screen.
for _, value in parser.parse_args()._get_kwargs():
if value is not None:
print(value)
Вот результат, который вы можете ожидать:
$ python arg.py --default 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567
$ python arg.py --list-type 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567
$ # Quotes won't help here...
$ python arg.py --list-type "1234 2345 3456 4567"
['1', '2', '3', '4', ' ', '2', '3', '4', '5', ' ', '3', '4', '5', '6', ' ', '4', '5', '6', '7']
$ python arg.py --list-type-nargs 1234 2345 3456 4567
[['1', '2', '3', '4'], ['2', '3', '4', '5'], ['3', '4', '5', '6'], ['4', '5', '6', '7']]
$ python arg.py --nargs 1234 2345 3456 4567
['1234', '2345', '3456', '4567']
$ python arg.py --nargs-int-type 1234 2345 3456 4567
[1234, 2345, 3456, 4567]
$ # Negative numbers are handled perfectly fine out of the box.
$ python arg.py --nargs-int-type -1234 2345 -3456 4567
[-1234, 2345, -3456, 4567]
$ python arg.py --append-action 1234 --append-action 2345 --append-action 3456 --append-action 4567
['1234', '2345', '3456', '4567']
Вынос :
- Используйте
nargs
илиaction='append'
nargs
может быть более простым с точки зрения пользователя, но он может быть не интуитивным, если есть позиционные аргументы, потому что argparse
не может сказать, что должно быть позиционным аргументом, а что принадлежит nargs
; если у вас есть позиционные аргументы, то action='append'
может оказаться лучшим выбором.
- Выше справедливо только , если
nargs
дано '*'
, '+'
или '?'
. Если вы укажете целое число (например, 4
), то не будет проблем с смешиванием опций nargs
и позиционных аргументов, потому что argparse
вы точно будете знать, сколько значений ожидать для опции.
- Не используйте кавычки в командной строке 1
- Не используйте
type=list
, так как он вернет список списков
- Это происходит потому, что под капотом
argparse
используется значение type
для приведения каждого отдельного заданного вами аргументаtype
, а не совокупность всех аргументов.
- Вы можете использовать
type=int
(или что-то еще), чтобы получить список целых (или что-то еще)
1 : я не имею в виду вообще ... я имею в виду, что использование кавычек для передачи спискаargparse
- это не то, что вам нужно.
type=list
опцию. Не используйте это. Это превращает строку в список, и, следовательно, списки списков.type
параметр для какого-либо другого объекта. По умолчанию этот метод возвращает список строк.--
может разделить варианты против позиционных аргументов.prog --opt1 par1 ... -- posp1 posp2 ...
--
помогает понять это, как показано в примере в моем предыдущем комментарии. Пользователь IOW поставляет--
все позиционные аргументы.Я предпочитаю передавать строку с разделителями, которую я анализирую позже в скрипте. Причины этого: список может быть любого типа
int
илиstr
, и иногдаnargs
я сталкиваюсь с проблемами, если есть несколько необязательных аргументов и позиционных аргументов.Затем,
или,
будет работать нормально Разделителем также может быть пробел, который, тем не менее, будет приводить кавычки вокруг значения аргумента, как в примере в вопросе.
источник
type
аргументlambda s: [int(time) for item in s.split(',')]
вместо постобработкиargs.list
.int(time)
должно бытьint(item)
. Мой пример был упрощенной версией того, что я обычно делаю, где я проверяю много других вещей, а не простую обработку. Но чтобы просто ответить на вопрос, я тоже нахожу твой путь более элегантным ..lambda items: list(csv.reader([items]))[0]
со стандартной библиотекой csv - модифицированная версия комментария от @chepner для всех, кто беспокоится о произвольном вводе CSV (ссылка: ответ от @adamk ).Кроме того
nargs
, вы можете использовать,choices
если вы знаете список заранее:источник
Использование параметра nargs nargs в методе argparse add_argument
Я использую nargs = ' ' в качестве параметра add_argument. Я специально использовал Nargs = ' ' для выбора значений по умолчанию, если я не передаю никаких явных аргументов
Включение фрагмента кода в качестве примера:
Пример: temp_args1.py
Обратите внимание: приведенный ниже пример кода написан на python3. Изменяя формат оператора печати, можно запустить в python2
Примечание: я собираю несколько строковых аргументов, которые хранятся в списке - opts.alist Если вы хотите получить список целых чисел, измените параметр типа в parser.add_argument на int
Результат выполнения:
источник
temp_args1.py -i [item5 ,item6, item7]
и сделать вывод в виде списка (вместо вложенного списка)Если вы собираетесь сделать так, чтобы один переключатель принимал несколько параметров, используйте
nargs='+'
. Если ваш пример '-l' на самом деле принимает целые числа:Производит
Если вы указываете один и тот же аргумент несколько раз, действие по умолчанию (
'store'
) заменяет существующие данные.Альтернатива - использовать
append
действие:Который производит
Или вы можете написать собственный обработчик / действие для разбора значений через запятую, чтобы вы могли сделать
источник
In
add_argument()
,type
это просто вызываемый объект, который получает строку и возвращает значение опции.Это позволит:
источник
Если у вас есть вложенный список, где внутренние списки имеют разные типы и длины, и вы хотите сохранить тип, например,
[[1, 2], ["foo", "bar"], [3.14, "baz", 20]]
тогда вы можете использовать решение, предложенное @ sam-mason для этого вопроса , показанное ниже:
который дает:
источник
Я хочу обрабатывать передачу нескольких списков, целочисленных значений и строк.
Полезная ссылка => Как передать переменную Bash в Python?
Порядок не важен. Если вы хотите , чтобы передать список просто сделать , как между ними
"["
и"]
и разделить их с помощью запятой.Затем,
Выход =>
['my_string', '3', ['1', '2'], ['3', '4', '5']]
,my_args
переменная содержит аргументы в порядке.источник
Я думаю, что самое элегантное решение - передать лямбда-функцию в тип, как упоминал Чепнер. В дополнение к этому, если вы заранее не знаете, каким будет разделитель вашего списка, вы также можете передать несколько разделителей в re.split:
источник
-l
в виду пример вызова? Откуда-n
взялся?parser.add_argument('-l', '--list', type = lambda s: re.split('[ ,;]', s))
. Вот вход:script.py -l abc xyz, abc\nxyz
. Наконец, вот результат:script.py: error: unrecognized arguments: xyz, abcnxyz