- 6 августа 2025
- 8 минут
- 536
Аргументы командной строки в Python
Статью подготовили специалисты образовательного сервиса Zaochnik.
Программный код можно условно разделить на две группы:
- приложения для командной строки и
- программы с графическим интерфейсом (при этом не будем учитывать специализированные сервисы для Windows и демоны под Linux).
Параметры, задаваемые при запуске с использованием командной строки, как правило используются в консольных приложениях.
Без использования библиотеки argparse
Для начала рассмотрим пример, в котором не используется библиотека argparse. Создадим простой скрипт на Python, который назовем `sampleprogram.py`. Так выглядит классический пример "Hello World", на котором мы будем базироваться.
```
#!/usr/bin/python
if __name__ == "__main__":
print("Hello World")
```
После завершения разработки заказчик остался доволен, но попросил добавить возможность передавать имя, которое мы приветствуем, сделав этот параметр необязательным. То есть программа должна правильно функционировать как при отсутствии имени, так и при его наличии.
Можно использовать переменную `argv` из модуля `sys`.
Массив `sys.argv` включает в себя список строк, представляющих параметры, переданные скрипту с использованием командной строки, где первый элемент — это имя самого скрипта.
Рассмотрим пример скрипта `params.py`:
```
#!/usr/bin/python
import sys
if __name__ == "__main__":
for param in sys.argv:
print(param)
```
Вот как можно выполнить его командой: ‘python params.py’.
В результате на консоли мы увидим: params.py.
Если добавим несколько аргументов: ‘python params.py param1 param2 param3’,
то вывод будет следующим:
params.py
param1
param2
param3
Важно заметить, что имя интерпретатора Python не включается в это множество, хотя оно присутствует в команде вызова.
Теперь вернемся к нашей задаче:
```
#!/usr/bin/python
import sys
if __name__ == "__main__":
if len(sys.argv) > 1:
print("Hello {}!".format(sys.argv[1]))
else:
print("Hello World")
```
Теперь, в случае, когда мы запустим программу используя командную строку: `python sampleprogram.py` -
вывод останется тем же: `Hello World`.
А если передастся параметр: `python sampleprogram.py Vasiliy`,
то мы получим: `Hello, Vasiliy!`
Пока все выглядит просто, но предположим, что требования заказчика изменились: имя приветствуемого должно передаваться через именованный параметр `--name` или `-n`, и при этом необходимо следить, чтобы было передано только одно имя. В этом случае код станет более запутанным.
```
#!/usr/bin/python
import sys
if __name__ == "__main__":
if len(sys.argv) == 1:
print("Hello World")
else:
if len(sys.argv) < 3:
print("Ошибка. Слишком мало параметров.")
sys.exit(1)
if len(sys.argv) > 3:
print("Ошибка. Слишком много параметров.")
sys.exit(1)
param_name = sys.argv[1]
param_value = sys.argv[2]
if param_name in ["--name", "-n"]:
print("Hello {}!".format(param_value))
else:
print("Ошибка. Неизвестный параметр '{}'".format(param_name))
sys.exit(1)
```
В этом коде мы проверяем разные условия: от отсутствия параметров до их избытка. Если все проверки пройдены успешно, программа выведет приветствие.
Однако такой код может быть сложным и неудобным для модификации, особенно если предстоит добавить новые параметры. Разумным шагом будет разделить логику программы и обработку параметров, однако для этого мы воспользуемся стандартной библиотекой Python — argparse, облегчающей разбор командной строки.
Использование библиотеки argparse
Аргументы командной строки можно удобно обрабатывать с помощью библиотеки argparse, которая автоматизирует верификацию переданных параметров, включая их количество и форму, после чего можно использовать их в логике приложения.
Ключевым элементом в работе с argparse выступает класс `ArgumentParser`. У него имеется множество параметров для конструктора и методов.
Основной принцип работы с argparse:
- Необходимо создать экземпляр класса `ArgumentParser`.
- Добавляем ожидаемые параметры через метод `add_argument`.
- Выделяем элементы командной строки при помощи метода `parse_args`, передавая ему параметры, кроме первого элемента.
- Используем полученные параметры в программе.
Представим, как будет выглядеть программа `sampleprogram.py` с использованием argparse. Мы предполагаем следующий синтаксис: `python sampleprogram.py [Имя]`
где [Имя] — это необязательный параметр.
Программа может выглядеть так:
```
#!/usr/bin/python
import sys
import argparse
def createParser():
parser = argparse.ArgumentParser()
parser.add_argument('name', nargs='?')
return parser
if __name__ == '__main__':
parser = createParser()
namespace = parser.parse_args()
if namespace.name:
print("Hello {}!".format(namespace.name))
else:
print("Hello World")
```
С первого взгляда, работа программы аналогична предыдущей версии, но существуют важные отличия, которые мы обсудим позже. Парсер вынесен в отдельную функцию, что упрощает будущие изменения. Экземпляр класса `ArgumentParser` создается с параметрами по умолчанию. С помощью метода `add_argument`, который рассматривается как позиционный, мы добавили ожидаемый параметр. Если бы мы не определили `nargs='?'`, такой параметр стал бы обязательным.
`nargs` способен принимать такие значения, как `?`, `+`, `*`, а также `argparse.REMAINDER`, которые применяются в сочетании с именованными параметрами.
Теперь мы можем вызвать метод `parse_args` для обработки параметров через командную строку. В случае, когда параметр не указан, передача осуществится всех элементов из `sys.argv`, исключая нулевой: `python parser.parse_args(sys.argv[1:])`
В результате мы получим экземпляр класса `Namespace`, в котором содержится переданное имя параметра. Если мы запустим программу с именем: `python sampleprogram.py Vasiliy`
то мы увидим:
python
Namespace(name=’Vasiliy’)
Если аргумент не передан - значение отобразится в виде `None`:
python
Namespace(name=None)
Мы можем установить значение по умолчанию, что сделает программу более компактной. Предположим, по умолчанию будет использовано слово "World". Это достигается с помощью именованного параметра `default` внутри метода `add_argument`:
```
#!/usr/bin/python
import sys
import argparse
def createParser():
parser = argparse.ArgumentParser()
parser.add_argument('name', nargs='?', default='World')
return parser
if __name__ == '__main__':
parser = createParser()
namespace = parser.parse_args(sys.argv[1:])
print("Hello {}!".format(namespace.name))
```
Таким образом, теперь программа продолжает функционировать так же, как и ранее. Заметно, как в метод `parse_args` передается параметр из списка `sys.argv`. Это служит для демонстрации того, что мы можем передавать параметры явно, хотя большинство обработки можно доверить библиотеке argparse.