Обработка аргументов командной строки в 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 автоматически генерирует справку, но может быть избыточен для простых скриптов.
Расширенные примеры обработки аргументов
Аргументы с выбором из нескольких вариантов (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') открывает файл для чтения.