python argparse, поиск определенного файла, если опция не указана

У меня есть аргумент для входного файла, и его легко обработать с помощью argparse

parser.add_argument( '-al', nargs = 1, type = argparse.FileType( 'r' ),
                     dest = 'alphabet' )

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

#if no alphabet look for .al file in current directory
if( args.alphabet == None ):
    AlFiles = [ f for f in os.listdir( '.' ) 
                if os.path.isfile( f ) and f.endswith( '.al' ) ]

    #there should be one file with .al extension
    if( len( AlFiles ) != 1 ):
            sys.exit( 'error: no alphabet file provided and '
                    'there are more than one or no .al file in current directory, '
                    'which leads to ambiguity' )

    args.alphabet = open( AlFiles[0], 'r' )

Есть ли в любом случае, чтобы выполнить это с argparse, возможно, с параметрами по умолчанию или действиями. Если я выполняю поиск до разбора аргументов и возникает исключительная ситуация, я все равно не могу вызвать ее, потому что требуемый файл может быть предоставлен аргументами командной строки. Я думал о выполнении действия, если парсер не соответствует требуемому параметру, но не может узнать, как это сделать с помощью argparse.

1 ответ

Решение

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

parser = argparse.ArgumentParser()
parser.add_argument('-al',
                    type = argparse.FileType('r'),
                    default = [ f for f in os.listdir( '.' )
                                if os.path.isfile( f ) and f.endswith( '.al' )],
                    dest = 'alphabet' )

А потом сделайте проверку. Таким образом, у вас есть только одна функция, проверяющая, существует ли более одного или ни одного *.al файла, был ли аргумент пропущен или нет.

Это может быть выполнено, например, следующим образом:

args =  parser.parse_args()
if isinstance(args.alphabet,types.ListType):
    if len(args.alphabet) != 1:
        parser.error("There must be exactly one alphabet in the directory")
    else:
        args.alphabet = open(args.alphabet[0])

Таким образом, args.alphabet будет содержать открытый файл, если был задан файл алфавита или в текущем рабочем каталоге только один файл алфавита, но выдаст ошибку, если в cwd больше или их нет.

Примечание: потому что мы получаем список, если -al аргумент опущен, argparse.FileType('r') не откроет ни одного файла. Вы также должны опустить nargs=1 поскольку это создаст список, содержащий один открытый файл, пользователь, указанный в -al аргумент. Пропуск этого атрибута даст нам необработанный открытый файл, указанный пользователем.

РЕДАКТИРОВАТЬ: вам придется import types,

Другие вопросы по тегам