Обработка аргументов командной строки в Python

Раздел: Python -> Функции

При разработке консольных приложений на Python часто требуется получать данные, переданные при запуске скрипта. Эти данные называются аргументами командной строки. Существует несколько способов их обработки, от простого ручного разбора до мощных библиотек. В этой статье рассматриваются основные подходы, их цели, случаи использования и типичные ошибки.

Обработка аргументов командной строки в Python

Наиболее эффективное решение: модуль argparse

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

Как сделать, чтобы скрипт принимал имя пользователя и опциональное приветствие?

import argparse

parser = argparse.ArgumentParser(description='Простое приветствие')
parser.add_argument('name', type=str, help='Имя пользователя')
parser.add_argument('-g', '--greeting', type=str, default='Привет', help='Текст приветствия')

args = parser.parse_args()
print(f'{args.greeting}, {args.name}!')

аргументы print python (аргументы функции print в python)

Пояснение: parser создаётся с описанием. add_argument добавляет позиционный аргумент name и опциональный -g/--greeting. parse_args() возвращает объект с атрибутами. Если аргумент не указан, используется значение по умолчанию.

$ python script.py Иван
Привет, Иван!

$ python script.py Иван --greeting Здравствуй
Здравствуй, Иван!

Python 3 аргументы (аргументы в python 3)

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

Как обработать аргументы без сторонних библиотек, используя sys.argv?

Модуль sys предоставляет список sys.argv, где первый элемент - имя скрипта, остальные - переданные аргументы. Этот способ подходит для простых скриптов без сложной логики.

import sys

if len(sys.argv) < 2:
    print('Ошибка: не указано имя')
    sys.exit(1)

name = sys.argv[1]
greeting = 'Привет'
if len(sys.argv) > 2:
    greeting = sys.argv[2]
print(f'{greeting}, {name}!')

аргумент параметр python (аргументы и параметры в python)

$ python script.py Мария
Привет, Мария!

$ python script.py Мария Здравствуйте
Здравствуйте, Мария!

аргумент класса python (аргументы класса python)

Проблемы: нет проверки типов, нет справки, при изменении порядка аргументов логика ломается. Индексная ошибка IndexError возникает, если аргументов меньше, чем ожидается. Решение - проверять длину списка перед доступом.

Как использовать getopt для разбора опций?

Модуль getopt (рекомендуется для совместимости с C-стилем) позволяет задавать короткие и длинные опции. Он устарел, но всё ещё встречается в старых проектах.

import sys, getopt

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'h:n:g:', ['help', 'name=', 'greeting='])
    except getopt.GetoptError as err:
        print(err)
        sys.exit(2)
    name = None
    greeting = 'Привет'
    for o, a in opts:
        if o in ('-h', '--help'):
            print('Usage: script.py -n <name> [-g <greeting>]')
            sys.exit()
        elif o in ('-n', '--name'):
            name = a
        elif o in ('-g', '--greeting'):
            greeting = a
    if not name:
        print('Ошибка: требуется имя')
        sys.exit(1)
    print(f'{greeting}, {name}!')

Python аргументы строки (аргументы строки в python (командная строка))

$ python script.py -n Анна -g Приветик
Приветик, Анна!

аргумент метода python (аргументы метода python)

Ошибки: неверный формат строки опций (двоеточие после опции означает, что требуется значение). Если опция не указана в строке, getopt не поймёт её. Также getopt не поддерживает значения по умолчанию - их нужно устанавливать вручную.

Как создать продвинутый CLI с помощью Click?

Библиотека click (сторонняя) предоставляет декларативный подход через декораторы. Удобна для создания сложных многоуровневых команд.

import click

@click.command()
@click.argument('name')
@click.option('-g', '--greeting', default='Привет', help='Приветствие')
def greet(name, greeting):
    click.echo(f'{greeting}, {name}!')

if __name__ == '__main__':
    greet()

Python args (аргументы в python)

$ python script.py Пётр -g Здорово
Здорово, Пётр!

Ошибки: не установленный click, конфликт имён с другими декораторами. Click автоматически генерирует справку, но может быть избыточен для простых скриптов.

- количество аргументов функции python (количество аргументов функции python)
- параметры и аргументы функции python (параметры и аргументы функции python)
- Python передать аргументы (передача аргументов в python)

Расширенные примеры обработки аргументов

Аргументы с выбором из нескольких вариантов (argparse)

Пример
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('action', choices=['start', 'stop', 'restart'], help='Действие')
parser.add_argument('--verbose', action='store_true', help='Подробный вывод')
args = parser.parse_args()
if args.verbose:
    print(f'Выполняю {args.action}...')
print(f'Действие: {args.action}')
$ python script.py start --verbose
Выполняю start...
Действие: start

$ python script.py pause
usage: script.py [-h] [--verbose] {start,stop,restart}
script.py: error: argument action: invalid choice: 'pause' (choose from 'start', 'stop', 'restart')

Пояснение: атрибут choices ограничивает возможные значения. action='store_true' делает флаг, который True, если опция указана.

Позиционные аргументы с переменным числом (nargs)

Пример
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('files', nargs='+', help='Файлы для обработки')
parser.add_argument('--output', '-o', default='result.txt', help='Выходной файл')
args = parser.parse_args()
print(f'Обрабатываются файлы: {args.files}')
print(f'Результат в: {args.output}')
$ python script.py a.txt b.txt c.txt -o out.txt
Обрабатываются файлы: ['a.txt', 'b.txt', 'c.txt']
Результат в: out.txt

nargs='+' требует хотя бы один аргумент. Можно использовать '*' для нуля или более.

Использование подкоманд (argparse subparsers)

Пример
import argparse

parser = argparse.ArgumentParser(description='Инструмент работы с данными')
subparsers = parser.add_subparsers(dest='command', required=True)

# подкоманда upload
upload_parser = subparsers.add_parser('upload', help='Загрузить файл')
upload_parser.add_argument('file', help='Имя файла')
upload_parser.add_argument('--server', default='localhost', help='Сервер')

# подкоманда download
download_parser = subparsers.add_parser('download', help='Скачать файл')
download_parser.add_argument('url', help='URL файла')
download_parser.add_argument('--dest', default='.', help='Папка назначения')

args = parser.parse_args()
if args.command == 'upload':
    print(f'Загрузка {args.file} на {args.server}')
elif args.command == 'download':
    print(f'Скачивание {args.url} в {args.dest}')
$ python script.py upload data.txt --server backup
Загрузка data.txt на backup

$ python script.py download http://example.com/file.zip --dest /tmp
Скачивание http://example.com/file.zip в /tmp

Подкоманды позволяют строить многофункциональные утилиты, как git.

Разбор аргументов с явным указанием типа и проверкой (argparse type)

Пример
import argparse

def positive_int(value):
    ivalue = int(value)
    if ivalue <= 0:
        raise argparse.ArgumentTypeError(f'{value} не является положительным целым')
    return ivalue

parser = argparse.ArgumentParser()
parser.add_argument('--count', type=positive_int, default=1, help='Количество (положительное целое)')
args = parser.parse_args()
print(f'Count = {args.count}')
$ python script.py --count 5
Count = 5

$ python script.py --count -3
usage: script.py [-h] [--count COUNT]
script.py: error: argument --count: -3 не является положительным целым

Пользовательская функция positive_int может проверять любые условия.

Пример с getopt для длинных опций и обработки ошибок

Пример
import sys, getopt

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'm:', ['mode=', 'verbose'])
    except getopt.GetoptError as err:
        print(f'Ошибка: {err}')
        sys.exit(2)
    mode = None
    verbose = False
    for o, a in opts:
        if o in ('-m', '--mode'):
            mode = a
        elif o == '--verbose':
            verbose = True
    print(f'Режим: {mode}, подробно: {verbose}')
    if args:
        print(f'Дополнительные аргументы: {args}')

if __name__ == '__main__':
    main()
$ python script.py --mode debug --verbose extra1 extra2
Режим: debug, подробно: True
Дополнительные аргументы: ['extra1', 'extra2']

$ python script.py -h
Ошибка: option -h not recognized

Обратите внимание: в getopt опции без значения не имеют двоеточия. Для --verbose двоеточие не нужно.

Использование Click с вложенными командами и контекстом

Пример
import click

@click.group()
def cli():
    pass

@cli.command()
@click.argument('name')
@click.option('--age', type=int, help='Возраст')
def hello(name, age):
    if age:
        click.echo(f'Привет, {name}! Тебе {age} лет.')
    else:
        click.echo(f'Привет, {name}!')

@cli.command()
@click.argument('file', type=click.File('r'))
@click.option('--lines', is_flag=True, help='Вывести количество строк')
def count(file, lines):
    content = file.read()
    if lines:
        click.echo(f'Строк: {content.count(chr(10)) + 1}')
    else:
        click.echo(f'Символов: {len(content)}')

if __name__ == '__main__':
    cli()
$ python script.py hello Алиса --age 30
Привет, Алиса! Тебе 30 лет.

$ python script.py count /etc/passwd --lines
Строк: 45

Click автоматически обрабатывает типы, файлы и флаги. type=click.File('r') открывает файл для чтения.

Аргументы строки в Python (командная строка) - comments

En
Python аргументы строки (python)