2016-10-15 3 views
0

Я хотел бы иметь возможность вводить аргументы командной строки в файл, а затем передавать их в программу python с помощью argparse, используя опцию а не префиксный символ, например: $ python myprogram.py 1 2 --foo 1 -A somefile.txt --bar 2 Это почти то же самое, что и this question, за исключением того, что мне нужно иметь некоторые позиционные аргументы в начале; когда это решение вызывает parse_args, оно терпит неудачу, если файл не имеет в нем позиционных аргументов.Как получить argparse для чтения аргументов из файла с опцией после позиционных аргументов

ответ

1

Если somefile.txt содержит

one 
two 
three 

затем

$ python myprogram.py 1 2 --foo 1 @somefile.txt --bar 2 

с помощью prefix char эффективно такой же, как

$ python myprogram.py 1 2 --foo 1 one two three --bar 2 

Другими словами, в самом начале синтаксического анализа, то @ файл считывается, и его содержимое сплайсируется в argv. Оттуда разбор происходит нормально.

Одна вещь, которую я предложил в другом вопросе SO, заключалась в том, чтобы реализовать это сращивание себя перед анализом.

Ответ, на который вы ссылаетесь, использует действие custom; в том месте, где обычно Action просто помещает value в namespace, это действие считывает и анализирует файл:

parser.parse_args(f.read().split(), namespace) 

Вариант разбирает в новые namespace и выборочно копия значений к основным namespace.

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

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

alt_parser.parse_args(f.read().split(), namespace) 

Другими словами, вы не должны использовать parser, который был передан в качестве параметра.

Вариация на это поместить имя файла в пространстве имен, и справиться с ней после первого разбора:

args = parser.parse_args() 
if args.A: 
    argv = open(args.A).read().split() 
    args1 = alt_parser.parse_args(argv) 

Но вы можете спросить, мы не можем сказать, какие аргументы уже проанализированы, и учитывайте это при обработке -A? parser не является государственной машиной; разбор не изменяет ни одного из его атрибутов. Единственной переменной, которая отражает синтаксический анализ до сих пор, является namespace. Все остальные переменные синтаксического анализа являются локальными для вызывающего кода.

+0

Должно было сказать: '@' делает все правильно, но я копирую поведение другой программы. Это имеет смысл; теперь трюк делает второй парсер с теми же аргументами, за исключением без обязательных позиционных. – petrelharp

+1

Сначала вы можете сделать этот синтаксический анализатор и использовать его как «родителей» для основного. Тогда вам просто нужно добавить 'positionals' в' child'. – hpaulj

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

  • Нет связанных вопросов^_^