Указание списка в качестве аргумента командной строки в python
Я использую getopt для обработки необязательного аргумента командной строки, который должен принимать список. Что-то вроде этого:
foo.py --my_list=[1, 2, 3, 4,5]
Но это все обрезает после "[1,"
Мои вопросы:
A) Есть ли способ указать список, не преобразовывая его в строку? (используя getopt)
B) Если мне нужно преобразовать список в строку, как преобразовать этот список в строку? например что-то вроде mylist.split( "?" ), чтобы избавиться от квадратных скобок??? есть лучший способ?
Спасибо
Ответы
Ответ 1
Есть два варианта, о которых я могу думать:
- Используйте optparse и используйте
append
, чтобы указать, что вы хотите сделать: foo.py --my_list=1 --my_list=2 ...
.
- Укажите свою командную строку как
foo.py --my_list='1,2,3,4,5'
, а затем используйте x.split(',')
, чтобы получить свои значения в списке. Вы можете использовать getopt
или optparse
для этого метода.
Преимущество первого метода заключается в том, что вы можете получить целые значения в списке напрямую, за счет удлинения командной строки (но вы можете добавить опцию one-charecter для --my_list
, если хотите). Преимуществом второй является более короткая командная строка, но после split()
вам нужно преобразовать значения строк '1'
, '2'
и т.д. В целые числа (довольно просто).
Ответ 2
Если я не могу использовать стандартный анализатор (optparse или argparse) для моего приложения, то я использую функцию ast.literal_eval для анализа входных аргументов списка типов следующим образом:
import sys, ast
inputList = ast.literal_eval( sys.argv[1] )
print type( inputList )
print inputList
Предположим, что этот код хранится в файле testParser.py. Выполняя script:
$ python testParser.py "[1,2,3,4, [123, 456, 789], 'asdasd']"
получаем следующий результат:
<type 'list'>
[1, 2, 3, 4, [123, 456, 789], 'asdasd']
Итак, используя достаточно надежную функцию ast.literal_eval и вставляя список в виде строки кода, мы получаем желаемый результат.
Полезные ссылки:
Использование eval() vython() vs. ast.literal_eval()?
http://docs.python.org/2/library/functions.html?highlight=eval#eval
Ответ 3
Может быть, вы должны просто заключить аргумент в кавычки?
foo.py "--my_list=[1, 2, 3, 4,5]"
В противном случае каждое пространство будет рассматриваться как разделитель для аргументов.
Ответ 4
На странице справки python optparse:
"
parser.add_option("-f")
parser.add_option("-p", type="float", nargs=3, dest="point")
Поскольку он анализирует командную строку
-f foo.txt -p 1 -3.5 4 -fbar.txt
optparse установит
options.f = "foo.txt"
options.point = (1.0, -3.5, 4.0)
options.f = "bar.txt"
"
Ответ 5
Обновленный способ - использовать библиотеку argparse
и добавить список в качестве аргумента командной строки. Таким образом, вам не нужно выполнять ручное разборку.
Пример:
parser = argparse.ArgumentParser()
parser.add_argument(
"-values",
nargs="*", # expects ≥ 0 arguments
type=int,
default=[35, 40, 50, 60, 70, 80, 90], # default list if no arg value
)
Что вы тогда вызывали бы так:
python3 someprogram.py -values 1 2 3