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

Обзор Поскольку Python является таким популярным языком программирования, а также поддерживает большинство операционных систем, он стал широко использоваться для создания инструментов командной строки для многих целей. Эти инструменты могут варьироваться от простых приложений с интерфейсом командной строки до более сложных, таких как инструмент AWS awscli [https://github.com/aws/aws-cli/]. Подобные сложные инструменты обычно управляются пользователем с помощью аргументов командной строки [https://en.wikipedia.org/wiki/Command-line_interface#Arguments], что позволяет пользователю

Обзор

Поскольку Python является таким популярным языком программирования, а также поддерживает большинство операционных систем, он стал широко использоваться для создания инструментов командной строки для многих целей. Эти инструменты могут варьироваться от простых приложений с интерфейсом командной строки до более сложных, таких как инструмент AWS awscli.

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

Обычно аргументы передаются инструментам CLI по-разному, в зависимости от вашей операционной системы:

  • Подобно Unix: - за которым следует буква, например -h , или -- за которым следует слово, например --help
  • Windows: / за которым следует буква или слово, например /help

Эти разные подходы существуют по историческим причинам. Многие программы в Unix-подобных системах поддерживают как одинарное, так и двойное тире. Обозначение одинарного тире в основном используется с однобуквенными параметрами, а двойное тире представляет собой более читаемый список параметров, что особенно полезно для сложных параметров, которые должны быть более явными.

Примечание . В этой статье мы сосредоточимся исключительно на Unix-подобном формате - и -- .

Имейте в виду, что и имя, и значение аргумента специфичны для программы

  • нет общего определения, кроме нескольких общих соглашений, таких как --help для получения дополнительной информации об использовании инструмента. Как разработчик сценария Python вы решаете, какие аргументы предоставить вызывающей стороне и что они будут делать. Это требует правильной оценки.

По мере роста вашего списка доступных аргументов ваш код станет более сложным в попытках их точного анализа. К счастью, в Python есть ряд библиотек, которые помогут вам в этом. Мы рассмотрим несколько наиболее распространенных решений, от «сделай сам» с sys.argv до подхода « argparse » с argparse.

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

Python 3 поддерживает несколько различных способов обработки аргументов командной строки. Встроенный способ - использовать модуль sys С точки зрения имен и использования, он имеет прямое отношение к библиотеке C ( libc ). Второй способ - это getopt , который обрабатывает как короткие, так и длинные параметры, включая оценку значений параметров.

Кроме того, существуют два других общих метода. Это модуль argparse , который является производным от optparse доступного до Python 2.7. Другой метод - использование модуля docopt , доступного на GitHub .

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

Модуль sys

Это базовый модуль, который с самого начала поставлялся с Python. Он использует подход, очень похожий на библиотеку C, с использованием argc / argv для доступа к аргументам. Модуль sys реализует аргументы командной строки в простой структуре списка с именем sys.argv .

Каждый элемент списка представляет собой единственный аргумент. Первый элемент в списке sys.argv[0] - это имя скрипта Python. Остальные элементы списка, от sys.argv[1] до sys.argv[n] , являются аргументами командной строки с 2 по n. В качестве разделителя между аргументами используется пробел. Значения аргументов, содержащие пробел, должны быть заключены в кавычки, чтобы их правильно проанализировал sys .

Эквивалент argc - это просто количество элементов в списке. Чтобы получить это значение, используйте оператор len() Позже мы покажем это на примере кода.

Печать первого аргумента CLI

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

 import sys 
 
 print ("The script has the name %s" % (sys.argv[0]) 

Сохраните этот код в файле с именем arguments-program-name.py, а затем вызовите его, как показано ниже. Результат выглядит следующим образом и содержит имя файла, включая его полный путь:

 $ python arguments-program-name.py 
 The script has the name arguments-program-name.py 
 $ python /home/user/arguments-program-name.py 
 The script has the name /home/user/arguments-program-name.py 

Как видно из второго вызова выше, мы получаем не только имя файла Python, но и полный путь, использованный для его вызова.

Подсчет количества аргументов

Во втором примере мы просто подсчитываем количество аргументов командной строки с помощью встроенного метода len() sys.argv - это список, который мы должны изучить. В приведенном ниже коде мы получаем количество аргументов и затем вычитаем 1, потому что один из этих аргументов (т.е. первый) всегда устанавливается как имя файла, что не всегда полезно для нас. Таким образом, фактическое количество аргументов, переданных пользователем, равно len(sys.argv) - 1 .

 import sys 
 
 # Count the arguments 
 arguments = len(sys.argv) - 1 
 print ("The script is called with %i arguments" % (arguments)) 

Сохраните и назовите этот файл arguments-count.py. Ниже приведены некоторые примеры вызова этого сценария. Это включает три разных сценария:

  • Вызов без дополнительных аргументов командной строки
  • Вызов с двумя аргументами
  • Вызов с двумя аргументами, где второй - строка в кавычках, содержащая пробел.
1
<!-- -->
 $ python arguments-count.py 
 The script is called with 0 arguments 
 $ python arguments-count.py --help me 
 The script is called with 2 arguments 
 $ python arguments-count.py --option "long string" 
 The script is called with 2 arguments 
Итерация по аргументам

В нашем третьем примере выводятся все аргументы, отправленные скрипту Python, за исключением самого имени программы. Поэтому мы перебираем аргументы командной строки, начиная со второго элемента списка. Напомним, что это индекс 1, поскольку списки в Python основаны на 0.

 import sys 
 
 # Count the arguments 
 arguments = len(sys.argv) - 1 
 
 # Output argument-wise 
 position = 1 
 while (arguments >= position): 
 print ("Parameter %i: %s" % (position, sys.argv[position])) 
 position = position + 1 

Ниже мы вызываем наш код, который был сохранен в файле arguments-output.py. Как и в предыдущем примере, на выходе показаны три разных вызова:

  • Звонок без аргументов
  • Вызов с двумя аргументами
  • Вызов с двумя аргументами, где второй аргумент - строка в кавычках, содержащая пробел.
1
<!-- -->
 $ python arguments-output.py 
 $ python arguments-output.py --help me 
 Parameter 1: --help 
 Parameter 2: me 
 $ python arguments-output.py --option "long string" 
 Parameter 1: --option 
 Parameter 2: long string 

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

Модуль getopt

Как вы могли заметить ранее, sys разбивает строку командной строки только на отдельные фасеты. Модуль Python getopt идет немного дальше и расширяет разделение входной строки проверкой параметров. Основанный на getopt , он позволяет использовать как короткие, так и длинные варианты, включая присвоение значений.

На практике для правильной обработки входных данных sys Для этого необходимо заранее загрузить как модуль sys getopt Затем из списка входных параметров мы удаляем первый элемент списка (см. Код ниже) и сохраняем оставшийся список аргументов командной строки в переменной с именем argument_list .

 # Include standard modules 
 import getopt, sys 
 
 # Get full command-line arguments 
 full_cmd_arguments = sys.argv 
 
 # Keep all but the first 
 argument_list = full_cmd_arguments[1:] 
 
 print argument_list 

Аргументы в argument_list теперь можно анализировать с помощью метода getopts() Но перед этим нам нужно сообщить getopts() о том, какие параметры допустимы. Они определены так:

 short_options = "ho:v" 
 long_options = ["help", "output=", "verbose"] 

Это означает, что эти аргументы мы считаем действительными, а также некоторую дополнительную информацию:

 ------------------------------------------ 
 long argument short argument with value 
 ------------------------------------------ 
 --help -h no 
 --output -o yes 
 --verbose -v no 
 ------------------------------------------ 

Вы могли заметить, что после o short ставится двоеточие : Это сообщает getopt что этой опции следует присвоить значение.

Теперь это позволяет нам обрабатывать список аргументов. Для getopt() необходимо настроить три параметра - список фактических аргументов из argv , а также допустимые короткие и длинные параметры (показаны в предыдущем фрагменте кода).

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

 try: 
 arguments, values = getopt.getopt(argument_list, short_options, long_options) 
 except getopt.error as err: 
 # Output error, and return with an error code 
 print (str(err)) 
 sys.exit(2) 

Наконец, аргументы с соответствующими значениями сохраняются в двух переменных с именами arguments и values . Теперь вы можете легко оценить эти переменные в своем коде. Мы можем использовать for для перебора списка распознанных аргументов, одна запись за другой.

 # Evaluate given options 
 for current_argument, current_value in arguments: 
 if current_argument in ("-v", "--verbose"): 
 print ("Enabling verbose mode") 
 elif current_argument in ("-h", "--help"): 
 print ("Displaying help") 
 elif current_argument in ("-o", "--output"): 
 print (("Enabling special output mode (%s)") % (current_value)) 

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

 $ python arguments-getopt.py -h 
 Displaying help 
 $ python arguments-getopt.py --help 
 Displaying help 
 $ python arguments-getopt.py --output=green --help -v 
 Enabling special output mode (green) 
 Displaying help 
 Enabling verbose mode 
 $ python arguments-getopt.py -verbose 
 option -e not recognized 

Последний вызов нашей программы поначалу может показаться немного запутанным. Чтобы понять это, вам нужно знать, что сокращенные параметры (иногда также называемые флагами) могут использоваться вместе с одним тире. Это позволяет вашему инструменту легче воспринимать множество вариантов. Например, вызов python arguments-getopt.py -vh аналогичен вызову python arguments-getopt.py -v -h . Таким образом, в последнем вызове выше getopt подумал, что пользователь пытается передать -e в качестве опции, что недопустимо.

Модуль argparse

Модуль argparse доступен начиная с Python 3.2 и является расширением optparse , существующим до Python 2.7. Документация Python содержит описание API и руководство, в котором подробно рассматриваются все методы.

Модуль предлагает интерфейс командной строки со стандартизованным выводом, тогда как первые два решения оставляют большую часть работы в ваших руках. argparse позволяет проверять фиксированные и необязательные аргументы с проверкой имени как в коротком, так и в длинном стиле. В качестве необязательного аргумента по умолчанию он включает -h вместе с его длинной версией --help . Этот аргумент сопровождается справочным сообщением по умолчанию, описывающим принятые аргументы.

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

 # Include standard modules 
 import argparse 
 
 # Initiate the parser 
 parser = argparse.ArgumentParser() 
 parser.parse_args() 

 $ python3 arguments-argparse-basic.py 
 $ python3 arguments-argparse-basic.py -h 
 usage: arguments-argparse-basic.py [-h] 
 
 optional arguments: 
 -h, --help show this help message and exit 
 $ python3 arguments-argparse-basic.py --verbose 
 usage: arguments-argparse-basic.py [-h] 
 arguments-argparse-basic.py: error: unrecognized arguments: --verbose 

На следующем этапе мы добавим настраиваемое описание в справочное сообщение для наших пользователей. Инициализация парсера таким образом позволяет добавить дополнительный текст. В приведенном ниже коде описание хранится в text переменной, которая явно argparse классу argparse в качестве параметра description Вызов этого кода ниже, вы можете увидеть, как выглядит результат.

 # Include standard modules 
 import argparse 
 
 # Define the program description 
 text = 'This is a test program. It demonstrates how to use the argparse module with a program description.' 
 
 # Initiate the parser with a description 
 parser = argparse.ArgumentParser(description=text) 
 parser.parse_args() 

 $ python3 arguments-argparse-description.py --help 
 usage: arguments-argparse-description.py [-h] 
 
 This is a test program. It demonstrates how to use the argparse module with a 
 program description. 
 
 optional arguments: 
 -h, --help show this help message and exit 

В качестве последнего шага мы добавим необязательный аргумент с именем -V , которому соответствует аргумент длинного стиля с именем --version . Для этого мы используем метод add_argument() который мы вызываем с тремя параметрами (отображается только для --version ):

  • Имя параметра: --version
  • Текст справки для параметра: help="show program version"
  • Действие (без дополнительного значения): action="store_true"

Исходный код для этого показан ниже. Считывание аргументов в переменную args выполняется с помощью parse_args() из объекта parser Обратите внимание, что вы отправляете как краткую, так и полную версию за один вызов. Наконец, вы проверяете, установлены ли атрибуты args.V или args.version , и выводите сообщение о версии.

 # Include standard modules 
 import argparse 
 
 # Initiate the parser 
 parser = argparse.ArgumentParser() 
 parser.add_argument("-V", "--version", help="show program version", action="store_true") 
 
 # Read arguments from the command line 
 args = parser.parse_args() 
 
 # Check for --version or -V 
 if args.version: 
 print("This is myprogram version 0.1") 

 $ python3 arguments-argparse-optional.py -V 
 This is myprogram version 0.1 
 $ python3 arguments-argparse-optional.py --version 
 This is myprogram version 0.1 

--version не требует указания значения в командной строке. Вот почему мы устанавливаем аргумент действия "store_true" . В других случаях вам может потребоваться дополнительное присвоенное значение, например, если вы укажете определенный объем, высоту или ширину. Это показано в следующем примере. Обратите внимание, что по умолчанию все аргументы интерпретируются как строки.

 # Include standard modules 
 import argparse 
 
 # Initiate the parser 
 parser = argparse.ArgumentParser() 
 
 # Add long and short argument 
 parser.add_argument("--width", "-w", help="set output width") 
 
 # Read arguments from the command line 
 args = parser.parse_args() 
 
 # Check for --width 
 if args.width: 
 print("Set output width to %s" % args.width) 

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

 $ python3 arguments-argparse-optional2.py -w 10 
 Set output width to 10 
 $ python3 arguments-argparse-optional2.py --width 10 
 Set output width to 10 
 $ python3 arguments-argparse-optional2.py -h 
 usage: arguments-argparse-optional2.py [-h] [--width WIDTH] 
 
 optional arguments: 
 -h, --help show this help message and exit 
 --width WIDTH, -w WIDTH 
 set output width 

Заключение

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

В этой статье мы не говорили о других решениях, таких как docopts , мы просто упомянули о нем. В этом модуле используется совершенно другой подход, и он будет подробно описан в одной из следующих статей.

Рекомендации

comments powered by Disqus

Содержание