Вторник, 02.01.2024 13:47

Разбираем (парсим) параметры командной строки в Python. Параметры командной строки в Python. Часть 1

Разбираем (парсим) параметры командной строки в Python. Параметры командной строки в Python. Часть 1

Python очень часто используется как скриптовый язык для написания простых программ. Сегодня мы рассмотрим способы разбора (парсинга) параметров командной строки при запуске скрипта или программы на Python из консоли.

Тестовый скрипт (программа)

Для начала напишем скрипт который что-то делает, в нашем случае он просто будет симулировать некий процесс:

print("Starting...")
print("1...")
print("2...")
print("3...")
print("Done!")

Сохраним его как 

script.py

Запустим:

python3 script.py
Starting...
1...
2...
3...
Done!

Чтобы было проще запускать создадим файл:

script.cmd

С содержимым:

@echo off
python3 script.py %*

Теперь всё параметры запуска будут передаваться нашему скрипту.

Модуль argparse

Для разбора параметров командной строки в Python мы будем использовать встроенный модуль argparse.

В этом модуле объявлен класс:

ArgumentParser

Данный класс позволяет задавать правила разбора параметров командной строки. C помощью метода add_argument() мы можем задавать как обязательные (позиционные) так необязательные  параметры.

Модуль args

Добавим модуль для нашего парсера командной строки.

Создадим файл:

args.py

с содержимым:

import argparse
parser = argparse.ArgumentParser(
    prog='script',
    description="Скрипт для демонстрации разбора (парсинга), параметров командной строки.",
)
args = parser.parse_args()

В начало файла script.py добавим строку:

from args import args

Запустим:

script
Starting...
1...
2...
3...
Done!

Ничего не поменялось так и должно быть так как мы задали правила для разбора командной строки.

Обязательные (позиционные) параметры

Вы можете указать один или несколько обязательных параметров. Обязательный параметр всегда начинается с буквы или цифры и должен обязательно указываться в том порядке, в котором он создан с помощью вызова метода add_argument. 

Добавим в файл:

args.py

После вызова:

argparse.ArgumentParser

код:

parser.add_argument(
    "command",
    type=str,
    help="Команда для запуска",
)

 Запустим:

script
usage: script [-h] command
script: error: the following arguments are required: command

Получим ошибку – Требуется аргумент - command

Запустим:

script run
Starting...
1...
2...
3...
Done!

Обрабатываем обязательный параметр

Мы передали скрипту команду, но наш парсер никак не обрабатывает и не определяет что это за команда.

На самом деле он и не должен этого делать, парсер занимается именно разбором командной строки и максимум, что он должен сделать – проверить тип параметра – строка, число или другой тип.

Вывод справки при запуске без параметров

Давайте добавим проверку на наличие первого параметра. Тут мы подразумеваем, что первый параметр у нас обязателен, так как это предотвращает случайный запуск скрипта.

В начало файла:

args.py

Добавим:

import sys

Перед строкой

args = parser.parse_args()

Добавим код:

if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)

Запустим:

script
usage: script [-h] command
Скрипт для демонстрации разбора (парсинга), параметров командной строки.
positional arguments:
  command     Команда для запуска
options:
  -h, --help  show this help message and exit

Теперь при запуске скрипта без параметров у нас будет выводится справка

Проверяем первый параметр

Теперь давайте добавим проверку является ли первый параметр допустимым.

Добавим в начало файла:

script.py
import sys

После:

from args import args

Добавим:

match args.command:
    case 'run':
        print("Запущена команда Run")  
    case _:
        print("Неизвестная команда: ", args.command, file=sys.stderr)        
        sys.exit(1)

Запустим:

script runn
Неизвестная команда:  runn

Запустим:

script run
Запущена команда Run
Starting...
1...
2...
3...
Done!

Несколько обязательных параметров

Возможно, вам потребуется передавать скрипту несколько обязательных параметров, например - имена файлов. Давайте рассмотрим как это сделать.

Изменим вызов метода:

parser.add_argument

Добавим новый параметр:

nargs=2

Этот параметр может принимать несколько значений:

N – (число) – количество обязательных параметров;

? – один параметр или ничего, в случае его отсутствия будет использовано значение default

* – любое количество параметров – может использоваться, если скрипту необходимо передавать много параметров.

+ – аналогичен значению *. Но есть отличие, если не задано ни одного параметра будет сгенерирована ошибка: 

error: the following arguments are required

Изменим метод:

parser.add_argument(
    "command",
    type=str,
    help="Команда для запуска",
    nargs=2
)

Внесем изменения в script.py закомментировав блок проверки параметров:

'''
match args.command:
    case 'run':
        print("Запущена команда Run")  
    case _:
        print("Неизвестная команда: ", args.command, file=sys.stderr)        
        sys.exit(1)
'''  

Добавим код для отладки полученных параметров:

print(args.command)

Запустим:

script file.txt file2.txt
['file.txt', 'file2.txt']
Starting...
1...
2...
3...
Done!

Если мы попробуем добавить лишний параметр, то получим ошибку:

script file.txt file2.txt file3.txt
usage: script [-h] command command
script: error: unrecognized arguments: file3.txt

Изменив на:

nargs="*"

Мы сможем задавать  любое количество параметров:

script file.txt file2.txt file3.txt file4.txt file5.txt file6.txt  
['file.txt', 'file2.txt', 'file3.txt', 'file4.txt', 'file5.txt', 'file6.txt']
Starting...
1...
2...
3...
Done!

Необязательные параметры

Необязательные параметры всегда должны начинаться со знака -- или -.

Вы можете указывать параметр как:

--param=value

так и:

--param value

Как следует из названия необязательные параметры могут и не присутствовать в командной строке и указываться в любом порядке.

Вы можете сразу указать несколько имен для параметров:

"--param1", "-param1","-p1"

В файл args.py добавим код:

parser.add_argument(
    "--param1","-param1","-p1",
    type=str,
    help="Необязательный параметр 1",    
)
 
parser.add_argument(
    "--param2","-param2","-p2",
    type=str,
    help="Необязательный параметр 2",    
)

Запустим:

script
usage: script [-h] [--param1 PARAM1] [--param2 PARAM2] [command]
Скрипт для демонстрации разбора (парсинга), параметров командной строки.
positional arguments:
  command               Команда для запуска
options:
  -h, --help            show this help message and exit
  --param1 PARAM1, -param1 PARAM1, -p1 PARAM1
                        Необязательный параметр 1
  --param2 PARAM2, -param2 PARAM2, -p2 PARAM2
                        Необязательный параметр 2

Парсер автоматически генерирует справку по параметрам, на основе указанных данных, это очень удобно!

Обратите внимание, название переменных в Python парсер генерирует на основе значения первой строки, например для строки:

"--param1","-param1","-p1",

Для нашего скрипта будет создана переменная :

args.param1

Изменим код для отладки параметров на:

print(args)

Запустим:

script run --param1=p1 --param2=p2
Namespace(command='run', param1='p1', param2='p2')
Starting...
1...
2...
3...
Done!

Теперь все переменные созданные из параметров командной строки будут нам доступны для просмотра:

Namespace(command='run', param1='p1', param2='p2')

Порядок необязательных параметров

Порядок необязательных параметров не имеет значения.

Запустим:

script run --param1=p1 --param2=p2
Namespace(command='run', param1='p1', param2='p2')
Starting...
1...
2...
3...
Done!

Запустим:

script run --param2=p2 --param1=p1
Namespace(command='run', param1='p1', param2='p2')
Starting...
1...
2...
3...
Done!

От перемены мест результат не меняется.

Несколько значений в необязательных параметрах

Используя:

nargs="*"

Мы можем задать для одного или нескольких параметров возможность указания нескольких параметров.

Изменим код параметра 1:

parser.add_argument(
    "--param1","-param1","-p1",
    type=str,
    help="Необязательный параметр 1",    
    nargs="*"
)

Запустим:

script run --param2=p2 --param1=p1
Namespace(command='run', param1=['p1'], param2='p2')
Starting...
1...
2...
3...
Done!

Обратите внимание, первый параметр у нас теперь является массивом!

Запустим:

script run --param2 p2 --param1 p1 p12 p13 p14 
Namespace(command='run', param1=['p1', 'p12', 'p13', 'p14'], param2='p2')
Starting...
1...
2...
3...
Done!

Порядок не имеет значения, запустим:

script run --param1 p1 p12 p13 p14 --param2 p2
Namespace(command='run', param1=['p1', 'p12', 'p13', 'p14'], param2='p2')
Starting...
1...
2...
3...
Done!

Несколько обязательных и необязательных параметров вместе

Давайте рассмотрим ситуацию, когда нам нужна следующая командная строка:

script run --param1 p1 p12 p13 p14 --param2 p2 file1.txt file2.txt file_n.txt

Т.е. в конце мы можем указать любое количество файлов, тогда код у нас меняется:

import argparse
import sys
 
parser = argparse.ArgumentParser(
    prog='script',
    description="Скрипт для демонстрации разбора (парсинга), параметров командной строки.",
)
 
parser.add_argument(
    "command",
    type=str,
    help="Команда для запуска",
    nargs=1
)

parser.add_argument(
    "--param1","-param1","-p1",
    type=str,
    help="Необязательный параметр 1",    
    nargs="*"
)

parser.add_argument(
    "--param2","-param2","-p2",
    type=str,
    help="Необязательный параметр 2",    
)

parser.add_argument(
    "files",
    type=str,
    help="Файлы для обработки",
    nargs="+"
)

if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)
 
args = parser.parse_args()

Запустим:

script run --param1 p1 p12 p13 p14 --param2 p2
usage: script [-h] [--param1 [PARAM1 ...]] [--param2 PARAM2] command files [files ...]
script: error: the following arguments are required: files

Так как мы не указали ни одного файла, то получили сообщение об ошибке.

Запустим:

script run --param1 p1 p12 p13 p14 --param2 p2 file1.txt file2.txt
Namespace(command=['run'], param1=['p1', 'p12', 'p13', 'p14'], param2='p2', files=['file1.txt', 'file2.txt'])
Starting...
1...
2...
3...
Done!

Всё работает как ожидалось!

Заключение

Сегодня мы рассмотрели разбор(парсинг) параметров командной строки в Python с помощью модуля argparse.

Определили что параметры делятся на обязательные (позиционные) и необязательные.

Рассмотрели обязательные (позиционные) параметры.

Рассмотрели необязательные параметры.

Рассмотрели способ разбора параметров с несколькими значениями.

Рассмотрели комбинации обязательных и необязательных параметров.

Категория Python
Теги Python

Добавить комментарий

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 160