Я разрабатываю инструмент командной строки с Python, функциональность которого разбита на несколько подкоманд, и в основном каждая принимает в качестве аргументов входные и выходные файлы. Сложность в том, что каждая команда требует разного количества параметров (некоторые не требуют выходного файла, некоторые требуют нескольких входных файлов и т. Д.).
В идеале интерфейс должен называться:
./test.py ncinfo inputfile
Затем синтаксический анализатор поймет, что команде ncinfo
требуется один аргумент (если он не соответствует команде ввода, он жалуется), и затем он вызывает функцию:
ncinfo(inputfile)
, которая делает реальную работу.
Когда команде требуется больше параметров, например
./test.py timmean inputfile outputfile
синтаксический анализатор осознает это, проверит, что действительно даны два аргумента, а затем он вызывает:
timmean(inputfile, outputfile)
Эта схема идеально обобщена для произвольного списка команд с 1 аргументом, команд с 2 аргументами и т. Д.
Однако я изо всех сил пытаюсь получить такое поведение с Python argparse
. Это то, что я до сих пор:
#! /home/navarro/SOFTWARE/anadonda3/bin/python
import argparse
# create the top-level parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# create the parser for the "ncinfo" command
parser_1 = subparsers.add_parser('ncinfo', help='prints out basic netCDF strcuture')
parser_1.add_argument('filein', help='the input file')
# create the parser for the "timmean" command
parser_2 = subparsers.add_parser('timmean', help='calculates temporal mean and stores it in output file')
parser_2.add_argument('filein', help='the input file')
parser_2.add_argument('fileout', help='the output file')
# parse the argument lists
parser.parse_args()
print(parser.filein)
print(parser.fileout)
Но это не работает, как ожидалось. Во-первых, когда я вызываю скрипт без аргументов, я не получаю сообщение об ошибке, сообщающее, какие у меня есть опции. Во-вторых, когда я пытаюсь запустить программу для использования ncinfo
, я получаю ошибку
./test.py ncinfo testfile
Traceback (most recent call last):
File "./test.py", line 21, in <module>
print(parser.filein)
AttributeError: 'ArgumentParser' object has no attribute 'filein'
Что я делаю неправильно, что мешает мне достичь желаемого поведения? Разумно ли в этом контексте использование subparsers
?
Бонус: есть ли способ обобщить определение команд, чтобы мне не нужно было добавлять вручную каждую команду? Например, сгруппировать все команды с одним аргументом в список, а затем определить анализатор в цикле. Это звучит разумно, но я не знаю, возможно ли это. В противном случае, по мере роста количества инструментов, сам синтаксический анализатор станет трудно поддерживать.