Указание списка в качестве аргумента командной строки в python
Я использую getopt для обработки необязательного аргумента командной строки, который должен принимать список. Что-то вроде этого:
foo.py --my_list=[1, 2, 3, 4,5]
Но это урезает все после "[1"
Мои вопросы: А) Есть ли способ указать список без преобразования его в строку? (используя getopt)
Б) Если я хочу преобразовать список в строку, как преобразовать этот список в строку? например, что-то вроде mylist.split("?"), чтобы избавиться от квадратных скобок?? Есть ли способ лучше?
Спасибо
6 ответов
Есть два варианта, которые я могу придумать:
- Используйте optparse и используйте
append
действие, чтобы указать, что вы хотите сделать как:foo.py --my_list=1 --my_list=2 ...
, - Укажите вашу командную строку как
foo.py --my_list='1,2,3,4,5'
, а затем использоватьx.split(',')
чтобы получить ваши значения в списке. Ты можешь использоватьgetopt
или жеoptparse
для этого метода.
Преимущество первого метода состоит в том, что вы можете получить целочисленные значения в списке напрямую, за счет более длинной командной строки (но вы можете добавить опцию с одним символом для --my_list
если ты хочешь). Преимущество второго заключается в более короткой командной строке, но после split()
необходимо преобразовать строковые значения '1'
, '2'
и т. д. до целых чисел (тоже довольно просто).
Если я не могу использовать стандартный синтаксический анализатор (optparse или argparse) для своего приложения, тогда я использую функцию ast.literal_eval для анализа входных аргументов типа list следующим образом:
import sys, ast
inputList = ast.literal_eval( sys.argv[1] )
print type( inputList )
print inputList
Предположим, что этот код хранится в файле testParser.py. Выполняя скрипт:
$ python testParser.py "[1,2,3,4, [123, 456, 789], 'asdasd']"
мы получаем следующий вывод:
<type 'list'>
[1, 2, 3, 4, [123, 456, 789], 'asdasd']
Итак, используя достаточно безопасную функцию ast.literal_eval и вставляя список в виде строки кода, мы получаем желаемый результат.
Полезные ссылки:
Используя python eval() против ast.literal_eval()?
http://docs.python.org/2/library/functions.html?highlight=eval
Может быть, вы должны просто заключить аргумент в кавычки?
foo.py "--my_list=[1, 2, 3, 4,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
Со страницы помощи 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"
"
Я был перенаправлен с двойного вопроса:
Как передать массив в Python через командную строку - переполнение стека
Я отвечаю на этот вопрос:
Аргументы в командной строке являются строками, они не анализируются как литералы в программе.
argv автоматически создает строки в список из аргументов командной строки (разделенных пробелами), короче говоря, sys.argv
это список.
from sys import argv
cmd = "arr = {sys.argv[1]}".format(argv)
exec(cmd)
print(arr[2])