optparse — анализатор параметров командной строки
Исходный код: Lib/optparse.py
Выбор библиотеки для разбора аргументов
В стандартную библиотеку входят три библиотеки для разбора аргументов:
-
getopt: модуль, практически повторяющий процедурный API языка Cgetopt. Входит в стандартную библиотеку ещё до первого выпуска Python 1.0. -
optparse: декларативная заменаgetopt, предоставляющая аналогичные возможности без необходимости реализовывать в каждом приложении собственную логику процедурного разбора параметров. Входит в стандартную библиотеку начиная с выпуска Python 2.3. -
argparse: более строгая альтернативаoptparse, предоставляющая больше возможностей по умолчанию, но уменьшающая гибкость приложения в управлении точным способом обработки аргументов. Входит в стандартную библиотеку начиная с выпусков Python 2.7 и Python 3.2.
Если нет особых ограничений на проектирование разбора аргументов, для реализации приложений командной строки рекомендуется использовать argparse: она обеспечивает наиболее широкий набор базовых возможностей при минимальном объёме кода на уровне приложения.
getopt сохранён почти исключительно ради обратной совместимости. Однако он также подходит для узкого случая использования: прототипирования и тестирования обработки аргументов командной строки в приложениях на C, основанных на getopt.
optparse стоит рассмотреть в качестве альтернативы argparse в следующих случаях:
- приложение уже использует
optparseи не хочет рисковать из-за тонких изменений поведения, которые могут возникнуть при переходе наargparse - приложению требуется дополнительный контроль над тем, как параметры и позиционные аргументы чередуются в командной строке (включая возможность полностью отключить чередование)
- приложению требуется дополнительный контроль над пошаговым разбором элементов командной строки (хотя
argparseэто поддерживает, конкретный способ работы на практике нежелателен для некоторых вариантов использования) - приложению требуется дополнительный контроль над обработкой параметров, принимающих значения, которые могут начинаться с
-(например, делегируемых параметров, передаваемых вызываемым подпроцессам) - приложению требуется другое поведение при обработке параметров командной строки, которое не поддерживается в
argparse, но может быть реализовано с помощью низкоуровневого интерфейса, предлагаемогоoptparse
По этим причинам optparse также, вероятно, станет более подходящей основой для авторов библиотек, создающих сторонние библиотеки обработки аргументов командной строки.
В качестве конкретного примера рассмотрим две следующие конфигурации разбора аргументов командной строки: первая использует optparse, а вторая — argparse:
import optparse
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.add_option('-o', '--output')
parser.add_option('-v', dest='verbose', action='store_true')
opts, args = parser.parse_args()
process(args, output=opts.output, verbose=opts.verbose)
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--output')
parser.add_argument('-v', dest='verbose', action='store_true')
parser.add_argument('rest', nargs='*')
args = parser.parse_args()
process(args.rest, output=args.output, verbose=args.verbose)
Самое очевидное различие состоит в том, что в варианте с optparse приложение отдельно обрабатывает аргументы, не являющиеся параметрами, после завершения обработки параметров. В варианте с argparse позиционные аргументы объявляются и обрабатываются так же, как именованные параметры.
Однако вариант с argparse также будет иначе обрабатывать некоторые сочетания параметров, чем вариант с optparse. Например (среди прочих различий):
- при передаче
-o -vсoptparseбудут полученыoutput="-v"иverbose=False, а сargparseвозникнет ошибка использования (с сообщением об отсутствии значения для-o/--output, поскольку-vинтерпретируется как флаг подробного вывода) - аналогично, при передаче
-o --сoptparseбудут полученыoutput="--"иargs=(), а сargparseвозникнет ошибка использования (также с сообщением об отсутствии значения для-o/--output, поскольку--интерпретируется как завершение обработки параметров и перевод всех оставшихся значений в позиционные аргументы) - при передаче
-o=fooсoptparseбудет полученоoutput="=foo", а сargparse—output="foo"(поскольку=специально обрабатывается как альтернативный разделитель значений параметров)
Считать ли такое различие в поведении варианта с argparse желательным или проблемным, зависит от конкретного сценария использования приложения командной строки.
См. также
click — сторонняя библиотека обработки аргументов (изначально основанная на optparse), позволяющая разрабатывать приложения командной строки в виде набора декорированных функций реализации команд.
Другие сторонние библиотеки, такие как typer или msgspec-click, позволяют задавать интерфейсы командной строки способами, которые лучше интегрируются со статической проверкой аннотаций типов Python.
Введение
optparse — более удобная, гибкая и мощная библиотека для разбора параметров командной строки, чем минималистичный модуль getopt. optparse использует более декларативный стиль разбора командной строки: вы создаёте экземпляр OptionParser, добавляете в него параметры и разбираете командную строку. optparse позволяет пользователям задавать параметры в традиционном синтаксисе GNU/POSIX, а также автоматически формирует для вас сообщения об использовании и справке.
Вот пример использования optparse в простом скрипте:
from optparse import OptionParser
...
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="don't print status messages to stdout")
(options, args) = parser.parse_args()
С этими несколькими строками кода пользователи вашего скрипта смогут выполнять в командной строке привычные действия, например:
<yourscript> --file=outfile -q
При разборе командной строки optparse задаёт атрибуты объекта options, возвращаемого методом parse_args(), на основе переданных пользователем значений командной строки. После завершения разбора этой командной строки методом parse_args() значение options.filename будет "outfile", а значение options.verbose — False. optparse поддерживает короткие и длинные параметры, позволяет объединять короткие параметры и допускает различные способы связывания параметров с их аргументами. Поэтому следующие командные строки эквивалентны приведённому выше примеру:
<yourscript> -f outfile --quiet <yourscript> --quiet --file outfile <yourscript> -q -foutfile <yourscript> -qfoutfile
Кроме того, пользователи могут выполнить одну из следующих команд
<yourscript> -h <yourscript> --help
и optparse выведет краткое описание параметров вашего скрипта:
Usage: <yourscript> [options] Options: -h, --help show this help message and exit -f FILE, --file=FILE write report to FILE -q, --quiet don't print status messages to stdout
где значение yourscript определяется во время выполнения (обычно из sys.argv[0]).
Предыстория
optparse был специально разработан для поощрения создания программ с простыми интерфейсами командной строки, соответствующими соглашениям, установленным семейством функций getopt(), доступных разработчикам на C. Поэтому он поддерживает только наиболее распространённые синтаксис и семантику командной строки, традиционно используемые в Unix. Если вы не знакомы с этими соглашениями, этот раздел поможет вам с ними ознакомиться.
Терминология
- аргумент
-
строка, введённая в командной строке и переданная оболочкой программе
execl()илиexecv(). В Python аргументы — это элементыsys.argv[1:](sys.argv[0]— имя выполняемой программы). В оболочках Unix также используется термин «слово».Иногда желательно подставить вместо
sys.argv[1:]другой список аргументов, поэтому под «аргументом» следует понимать «элементsys.argv[1:]или другого списка, предоставленного вместоsys.argv[1:]». - параметр
-
аргумент, используемый для передачи дополнительных сведений, управляющих выполнением программы или настраивающих его. Для параметров существует множество синтаксисов; традиционный синтаксис Unix — дефис («-»), за которым следует одна буква, например
-xили-F. Кроме того, традиционный синтаксис Unix позволяет объединять несколько параметров в один аргумент, например-x -Fэквивалентно-xF. В проекте GNU был введён синтаксис--, за которым следует несколько разделённых дефисами слов, например--fileили--dry-run. Это единственные два синтаксиса параметров, поддерживаемыеoptparse.Существуют и другие синтаксисы параметров, например:
- дефис, за которым следуют несколько букв, например
-pf(это не то же самое, что несколько параметров, объединённых в один аргумент) - дефис, за которым следует целое слово, например
-file(технически это эквивалентно предыдущему синтаксису, но обычно они не встречаются в одной и той же программе) - знак плюса, за которым следует одна буква, несколько букв или слово, например
+f,+rgb - косая черта, за которой следует одна буква, несколько букв или слово, например
/f,/file
Эти синтаксисы параметров не поддерживаются
optparseи никогда не будут поддерживаться. Это сделано намеренно: первые три нестандартны во всех средах, а последний имеет смысл только при разработке исключительно для Windows или некоторых устаревших платформ (например, VMS, MS-DOS). - дефис, за которым следуют несколько букв, например
- аргумент параметра
-
аргумент, следующий за параметром, тесно связанный с ним и извлекаемый из списка аргументов вместе с этим параметром. В
optparseаргументы параметров могут указываться отдельно от параметра:-f foo --file foo
или включаться в тот же аргумент:
-ffoo --file=foo
Обычно конкретный параметр либо принимает аргумент, либо нет. Многие хотят иметь возможность указывать «необязательные аргументы параметров», то есть чтобы некоторые параметры принимали аргумент, если он указан, и не принимали, если он не указан. Это вызывает споры, поскольку делает разбор неоднозначным: если
-aпринимает необязательный аргумент, а-b— это другой параметр, как следует интерпретировать-ab? Из-за этой неоднозначностиoptparseне поддерживает такую возможность. - позиционный аргумент
-
элемент, оставшийся в списке аргументов после разбора параметров, то есть после разбора параметров и их аргументов и удаления их из списка аргументов.
- обязательный параметр
-
параметр, который необходимо указать в командной строке; обратите внимание, что выражение «обязательный параметр» внутренне противоречиво.
optparseне мешает реализовать обязательные параметры, но и почти не помогает в этом.
Например, рассмотрим следующую гипотетическую командную строку:
prog -v --report report.txt foo bar
-v и --report — это параметры. Если предположить, что --report принимает один аргумент, то report.txt — аргумент параметра. foo и bar — позиционные аргументы.
Для чего нужны параметры?
Параметры используются для передачи дополнительных сведений, позволяющих настроить или изменить выполнение программы. На всякий случай уточним: параметры обычно необязательны. Программа должна нормально работать и вовсе без параметров. (Возьмите наугад любую программу из набора инструментов Unix или GNU. Может ли она работать без параметров и при этом оставаться полезной? Главные исключения — find, tar и dd — все они являются странными исключениями, заслуженно критикуемыми за нестандартный синтаксис и запутанные интерфейсы.)
Многие хотят, чтобы в их программах были «обязательные параметры». Подумайте об этом. Если что-то обязательно, значит, оно не является необязательным! Если программе для успешной работы непременно нужны какие-либо сведения, для этого и существуют позиционные аргументы.
В качестве примера удачного проектирования интерфейса командной строки рассмотрим скромную утилиту cp для копирования файлов. Копировать файлы без указания места назначения и хотя бы одного исходного файла не имеет смысла. Поэтому cp завершается с ошибкой, если запустить её без аргументов. Однако у неё есть гибкий и удобный синтаксис, не требующий никаких параметров:
cp SOURCE DEST cp SOURCE ... DEST-DIR
Этого уже достаточно для многих задач. Большинство реализаций cp предоставляют множество параметров для точной настройки способа копирования файлов: можно сохранять права доступа и время изменения, не переходить по символическим ссылкам, запрашивать подтверждение перед перезаписью существующих файлов и т. д. Но всё это не отвлекает от основной задачи cp — копирования одного файла в другой или нескольких файлов в другой каталог.
Для чего нужны позиционные аргументы?
Позиционные аргументы предназначены для тех сведений, которые совершенно необходимы вашей программе для работы.
Удобный интерфейс должен предъявлять как можно меньше безусловных требований. Если для успешной работы программе нужны 17 отдельных сведений, не так уж важно, как вы получаете их от пользователя: большинство людей сдадутся и уйдут, так и не запустив программу. Это справедливо для любого пользовательского интерфейса: командной строки, файла конфигурации или графического интерфейса. Если предъявлять пользователям столько требований, большинство из них просто откажутся от программы.
Короче говоря, старайтесь свести к минимуму количество сведений, которые пользователи обязаны указывать, и по возможности используйте разумные значения по умолчанию. Конечно, программы также должны быть достаточно гибкими. Для этого и нужны параметры. Неважно, представлены ли они записями в файле конфигурации, элементами управления в диалоговом окне «Настройки» графического интерфейса или параметрами командной строки: чем больше параметров вы реализуете, тем гибче программа и тем сложнее её реализация. Чрезмерная гибкость тоже имеет недостатки: слишком большое количество параметров может перегрузить пользователей и значительно усложнить сопровождение кода.
Руководство
Хотя optparse довольно гибок и мощен, в большинстве случаев его также просто использовать. В этом разделе рассматриваются шаблоны кода, общие для всех программ на основе optparse.
Сначала нужно импортировать класс OptionParser; затем, в начале основной программы, создать экземпляр OptionParser:
from optparse import OptionParser ... parser = OptionParser()
Теперь можно приступить к определению параметров. Основной синтаксис:
parser.add_option(opt_str, ...,
attr=value, ...)
У каждого параметра есть одна или несколько строк параметров, например -f или --file, а также несколько атрибутов параметра, которые указывают optparse, чего ожидать и что делать при обнаружении этого параметра в командной строке.
Обычно для каждого параметра задаются одна короткая и одна длинная строка параметра, например:
parser.add_option("-f", "--file", ...)
Можно определить сколько угодно коротких и длинных строк параметров (в том числе ни одной), если в совокупности задана хотя бы одна строка параметра.
Строки параметров, переданные в OptionParser.add_option(), фактически являются метками параметра, определяемого этим вызовом. Для краткости мы часто будем говорить об обнаружении параметра в командной строке; на самом деле optparse обнаруживает строки параметров и находит по ним параметры.
Определив все параметры, укажите optparse разобрать командную строку программы:
(options, args) = parser.parse_args()
(При желании в parse_args() можно передать пользовательский список аргументов, но это редко требуется: по умолчанию используется sys.argv[1:].)
parse_args() возвращает два значения:
-
options— объект, содержащий значения всех параметров; например, если--fileпринимает один строковый аргумент, тоoptions.fileбудет именем файла, указанным пользователем, илиNone, если пользователь не указал этот параметр -
args— список позиционных аргументов, оставшихся после разбора параметров
В этом разделе руководства рассматриваются только четыре наиболее важных атрибута параметров: action, type, dest (назначение) и help. Из них action — самый важный.
Понимание действий параметров
Действия указывают optparse, что делать при обнаружении параметра в командной строке. В optparse жестко задан фиксированный набор действий; добавление новых действий — продвинутая тема, рассматриваемая в разделе Расширение optparse. Большинство действий указывают optparse сохранить значение в некоторой переменной — например, взять строку из командной строки и сохранить ее в атрибуте options.
Если не указать действие параметра, по умолчанию optparse использует store.
Действие store
Наиболее распространенное действие параметра — store. Оно указывает optparse взять следующий аргумент (или остаток текущего аргумента), проверить, что он имеет правильный тип, и сохранить его в выбранном вами месте назначения.
Например:
parser.add_option("-f", "--file",
action="store", type="string", dest="filename")
Теперь составим фиктивную командную строку и попросим optparse разобрать ее:
args = ["-f", "foo.txt"] (options, args) = parser.parse_args(args)
Когда optparse встречает строку параметра -f, он использует следующий аргумент, foo.txt, и сохраняет его в options.filename. Таким образом, после этого вызова parse_args() значение options.filename равно "foo.txt".
Среди других типов параметров, поддерживаемых optparse, есть int и float. Вот параметр, ожидающий целочисленный аргумент:
parser.add_option("-n", type="int", dest="num")
Обратите внимание, что у этого параметра нет длинной строки параметра, что вполне допустимо. Кроме того, действие явно не задано, поскольку по умолчанию используется store.
Разберем еще одну фиктивную командную строку. На этот раз мы присоединим аргумент параметра непосредственно к самому параметру: поскольку -n42 (один аргумент) эквивалентно -n 42 (двум аргументам), код
(options, args) = parser.parse_args(["-n42"]) print(options.num)
выведет 42.
Если не указать тип, optparse предполагает string. С учетом того, что действием по умолчанию является store, наш первый пример можно значительно сократить:
parser.add_option("-f", "--file", dest="filename")
Если не указать место назначения, optparse выберет подходящее значение по умолчанию на основе строк параметров: если первая длинная строка параметра — --foo-bar, то местом назначения по умолчанию будет foo_bar. Если длинных строк параметров нет, optparse проверяет первую короткую строку параметра: местом назначения по умолчанию для -f будет f.
optparse также включает встроенный тип complex. Добавление типов рассматривается в разделе Расширение optparse.
Обработка логических параметров (флагов)
Параметры-флаги, устанавливающие переменную в значение true или false при обнаружении определенного параметра, встречаются довольно часто. optparse поддерживает их с помощью двух отдельных действий: store_true и store_false. Например, у вас может быть флаг verbose, который включается с помощью -v и выключается с помощью -q:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")
Здесь у нас два разных параметра с одним и тем же местом назначения, что вполне допустимо. (Это лишь означает, что нужно быть немного осторожнее при задании значений по умолчанию — см. ниже.)
Когда optparse встречает в командной строке -v, он устанавливает options.verbose в значение True; при обнаружении -q переменной options.verbose присваивается значение False.
Другие действия
Среди других действий, поддерживаемых optparse:
-
"store_const" -
сохранить постоянное значение, предварительно заданное с помощью
Option.const -
"append" -
добавить аргумент этого параметра в список
-
"count" -
увеличить счетчик на единицу
-
"callback" -
вызвать указанную функцию
Эти действия рассматриваются в разделе Справочное руководство и в разделе Обратные вызовы параметров.
Значения по умолчанию
Во всех приведенных выше примерах при обнаружении определенных параметров командной строки устанавливается значение некоторой переменной («места назначения»). Что произойдет, если эти параметры так и не будут обнаружены? Поскольку мы не задали значения по умолчанию, для всех них будет установлено None. Обычно этого достаточно, но иногда нужен больший контроль. optparse позволяет задать значение по умолчанию для каждого места назначения; оно присваивается до разбора командной строки.
Сначала рассмотрим пример с параметрами verbose/quiet. Если нужно, чтобы optparse присваивал verbose значение True, если не указан -q, можно сделать так:
parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")
Поскольку значения по умолчанию относятся к месту назначения, а не к какому-либо конкретному параметру, и у этих двух параметров одно и то же место назначения, это полностью эквивалентно следующему:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Рассмотрим такой пример:
parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)
И снова значением по умолчанию для verbose будет True: учитывается последнее значение по умолчанию, заданное для конкретного места назначения.
Более понятный способ задания значений по умолчанию — метод set_defaults() класса OptionParser, который можно вызвать в любой момент до вызова parse_args():
parser.set_defaults(verbose=True) parser.add_option(...) (options, args) = parser.parse_args()
Как и прежде, учитывается последнее значение, заданное для места назначения данного параметра. Для ясности используйте один из двух способов задания значений по умолчанию, но не оба сразу.
Создание справки
Возможность optparse автоматически создавать справку и текст использования полезна для создания удобных интерфейсов командной строки. Достаточно задать значение help для каждого параметра и, при желании, краткое сообщение об использовании всей программы. Вот OptionParser с удобными для пользователя (документированными) параметрами:
usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=True,
help="make lots of noise [default]")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose",
help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
metavar="FILE", help="write output to FILE")
parser.add_option("-m", "--mode",
default="intermediate",
help="interaction mode: novice, intermediate, "
"or expert [default: %default]")
Если optparse встретит в командной строке -h или --help либо если просто вызвать parser.print_help(), он выведет в стандартный поток вывода следующее:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
(Если вывод справки вызван параметром справки, optparse завершает работу после вывода текста справки.)
Здесь многое сделано для того, чтобы optparse мог создать наилучшее возможное сообщение справки:
-
скрипт задает собственное сообщение об использовании:
usage = "usage: %prog [options] arg1 arg2"
optparseподставляет вместо%progв строке использования имя текущей программы, то естьos.path.basename(sys.argv[0]). Развернутая строка затем выводится перед подробной справкой о параметрах.Если не задать строку использования,
optparseиспользует незамысловатое, но подходящее значение по умолчанию:"Usage: %prog [options]". Оно подойдет, если скрипт не принимает позиционных аргументов. - для каждого параметра задается строка справки; при этом не нужно беспокоиться о переносе строк —
optparseсам позаботится о переносах и удобном оформлении вывода справки. -
в автоматически создаваемом сообщении справки указывается, что параметры принимают значение, например для параметра «mode»:
-m MODE, --mode=MODE
Здесь «MODE» называется метапеременной: она обозначает аргумент, который пользователь должен передать в
-m/--mode. По умолчаниюoptparseпреобразует имя переменной назначения в верхний регистр и использует его в качестве метапеременной. Иногда это нежелательно — например, параметр--filenameявно задаетmetavar="FILE", в результате чего автоматически создается такое описание параметра:-f FILE, --filename=FILE
Это важно не только для экономии места: в справке, написанной вручную, используется метапеременная
FILE, чтобы дать пользователю понять, что между полуформальной записью-f FILEи неформальным смысловым описанием «записать вывод в FILE» есть связь. Это простой, но эффективный способ сделать справку намного понятнее и полезнее для конечных пользователей. - если у параметра есть значение по умолчанию, в строку справки можно включить
%default—optparseзаменит его наstr()значения параметра по умолчанию. Если у параметра нет значения по умолчанию (или его значение по умолчанию равноNone),%defaultзаменяется наnone.
Группировка параметров
При работе с большим количеством параметров удобно группировать их, чтобы улучшить вывод справки. Объект OptionParser может содержать несколько групп параметров, каждая из которых может содержать несколько параметров.
Группа параметров создается с помощью класса OptionGroup:
-
class optparse.OptionGroup(parser, title, description=None) -
где
- parser — экземпляр
OptionParser, в который будет добавлена группа - title — заголовок группы
- description, необязательный параметр, — подробное описание группы
- parser — экземпляр
OptionGroup наследуется от OptionContainer (как и OptionParser), поэтому для добавления параметра в группу можно использовать метод add_option().
После объявления всех параметров группа добавляется в ранее созданный анализатор с помощью его метода OptionParser add_option_group().
Продолжая работу с анализатором, определенным в предыдущем разделе, добавить в него OptionGroup очень просто:
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
В результате будет выведена следующая справка:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Более полный пример может включать несколько групп; продолжим предыдущий пример:
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action="store_true",
help="Print debug information")
group.add_option("-s", "--sql", action="store_true",
help="Print all SQL statements executed")
group.add_option("-e", action="store_true", help="Print every action done")
parser.add_option_group(group)
в результате будет получен следующий вывод:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or expert
[default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Debug Options:
-d, --debug Print debug information
-s, --sql Print all SQL statements executed
-e Print every action done
Еще один интересный метод, особенно полезный при программной работе с группами параметров:
-
OptionParser.get_option_group(opt_str) -
Возвращает
OptionGroup, к которой относится короткая или длинная строка параметра opt_str (например,'-o'или'--option'). Если такойOptionGroupнет, возвращаетNone.
Вывод строки версии
Подобно краткому сообщению об использовании, optparse может также выводить строку версии вашей программы. Эту строку нужно передать в качестве аргумента version для OptionParser:
parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
%prog разворачивается так же, как и в usage. В остальном version может содержать все, что угодно. Если задать этот аргумент, optparse автоматически добавит в анализатор параметр --version. Если этот параметр встретится в командной строке, программа развернет строку version (заменив %prog), выведет ее в stdout и завершит работу.
Например, если ваш скрипт называется /usr/bin/foo:
$ /usr/bin/foo --version foo 1.0
Для вывода и получения строки version можно использовать следующие два метода:
-
OptionParser.print_version(file=None) -
Выводит сообщение о версии текущей программы (
self.version) в file (по умолчанию — stdout). Как и в случае сprint_usage(), все вхождения%progвself.versionзаменяются именем текущей программы. Ничего не делает, еслиself.versionпуст или не определен.
-
OptionParser.get_version() -
То же, что и
print_version(), но возвращает строку версии, а не выводит ее.
Как optparse обрабатывает ошибки
optparse приходится иметь дело с двумя основными классами ошибок: ошибками программиста и ошибками пользователя. Ошибки программиста обычно связаны с некорректными вызовами OptionParser.add_option(), например с недопустимыми строками параметров, неизвестными атрибутами параметров, отсутствующими атрибутами параметров и т. д. Они обрабатываются обычным образом: вызывается исключение (либо optparse.OptionError, либо TypeError), и программа аварийно завершает работу.
Обработка ошибок пользователя гораздо важнее, поскольку они гарантированно будут возникать независимо от стабильности вашего кода. optparse может автоматически обнаруживать некоторые ошибки пользователя, например некорректные аргументы параметров (передача -n 4x, когда -n принимает целочисленный аргумент) и отсутствие аргументов (-n в конце командной строки, когда -n принимает аргумент любого типа). Кроме того, можно вызвать OptionParser.error(), чтобы сообщить об ошибке, определенной приложением:
(options, args) = parser.parse_args()
...
if options.a and options.b:
parser.error("options -a and -b are mutually exclusive")
В обоих случаях optparse обрабатывает ошибку одинаково: выводит сообщение об использовании программы и сообщение об ошибке в стандартный поток ошибок, а затем завершает работу с кодом ошибки 2.
Рассмотрим первый пример выше, в котором пользователь передает 4x параметру, принимающему целое число:
$ /usr/bin/foo -n 4x Usage: foo [options] foo: error: option -n: invalid integer value: '4x'
Или случай, когда пользователь вообще не передает значение:
$ /usr/bin/foo -n Usage: foo [options] foo: error: -n option requires an argument
Сообщения об ошибках, создаваемые optparse, всегда указывают параметр, вызвавший ошибку; не забывайте делать то же самое, вызывая OptionParser.error() из кода приложения.
Если стандартное поведение optparse при обработке ошибок вам не подходит, потребуется создать подкласс OptionParser и переопределить его методы exit() и/или error().
Собираем все вместе
Скрипты на основе optparse обычно выглядят так:
from optparse import OptionParser
...
def main():
usage = "usage: %prog [options] arg"
parser = OptionParser(usage)
parser.add_option("-f", "--file", dest="filename",
help="read data from FILENAME")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose")
...
(options, args) = parser.parse_args()
if len(args) != 1:
parser.error("incorrect number of arguments")
if options.verbose:
print("reading %s..." % options.filename)
...
if __name__ == "__main__":
main()
Справочное руководство
Создание парсера
Первый шаг при использовании optparse — создание экземпляра OptionParser.
-
class optparse.OptionParser(...) -
Конструктор OptionParser не имеет обязательных аргументов, но принимает несколько необязательных именованных аргументов. Всегда передавайте их как именованные аргументы, то есть не полагайтесь на порядок объявления аргументов.
-
usage (default: "%prog [options]") -
Краткое описание использования, выводимое при неправильном запуске программы или при запуске с параметром справки. Когда
optparseвыводит строку описания использования, она заменяет%progнаos.path.basename(sys.argv[0])(или наprog, если передан этот именованный аргумент). Чтобы отключить сообщение об использовании, передайте специальное значениеoptparse.SUPPRESS_USAGE. -
option_list (default: []) -
Список объектов Option, которыми нужно заполнить парсер. Параметры из
option_listдобавляются после параметров изstandard_option_list(атрибута класса, который могут задавать подклассы OptionParser), но перед параметрами версии и справки. Устарело; вместо этого после создания парсера используйтеadd_option(). -
option_class (default: optparse.Option) -
Класс, используемый при добавлении параметров в парсер с помощью
add_option(). -
version (default: None) -
Строка версии, выводимая, когда пользователь указывает параметр версии. Если для
versionуказано истинное значение,optparseавтоматически добавляет параметр версии с единственной строкой параметра--version. Подстрока%progзаменяется так же, как и дляusage. -
conflict_handler (default: "error") -
Задает, что делать при добавлении в парсер параметров с конфликтующими строками параметров; см. раздел Конфликты между параметрами.
-
description (default: None) -
Абзац с кратким обзором вашей программы.
optparseформатирует этот абзац в соответствии с текущей шириной терминала и выводит его, когда пользователь запрашивает справку (послеusage, но перед списком параметров). -
formatter (default: a new IndentedHelpFormatter) -
Экземпляр optparse.HelpFormatter, используемый для вывода текста справки. Для этой цели
optparseпредоставляет два конкретных класса: IndentedHelpFormatter и TitledHelpFormatter. -
add_help_option (default: True) -
Если значение истинно,
optparseдобавит в парсер параметр справки (со строками параметров-hи--help). -
prog -
Строка, используемая вместо
os.path.basename(sys.argv[0])при подстановке%progвusageиversion. -
epilog (default: None) -
Абзац текста справки, выводимый после описания параметров.
-
Заполнение парсера
Есть несколько способов добавить параметры в парсер. Рекомендуемый способ — использовать OptionParser.add_option(), как показано в разделе Руководство. add_option() можно вызвать одним из двух способов:
- передать ему экземпляр Option (возвращаемый
make_option()) - передать ему любую комбинацию позиционных и именованных аргументов, допустимых для
make_option()(то есть для конструктора Option), и он создаст экземпляр Option самостоятельно
Другой вариант — передать конструктору OptionParser список предварительно созданных экземпляров Option, например:
option_list = [
make_option("-f", "--filename",
action="store", type="string", dest="filename"),
make_option("-q", "--quiet",
action="store_false", dest="verbose"),
]
parser = OptionParser(option_list=option_list)
(make_option() — фабричная функция для создания экземпляров Option; в настоящее время это псевдоним конструктора Option. В будущей версии optparse класс Option может быть разделен на несколько классов, и make_option() выберет подходящий класс для создания экземпляра. Не создавайте экземпляры Option напрямую.)
Определение параметров
Каждый экземпляр Option представляет набор равнозначных строк параметров командной строки, например -f и --file. Можно указать любое количество коротких или длинных строк параметров, но нужно указать хотя бы одну строку параметра.
Стандартный способ создания экземпляра Option — метод add_option() класса OptionParser.
-
OptionParser.add_option(option) - OptionParser.add_option(*opt_str, attr=value, ...)
-
Чтобы определить параметр только с короткой строкой:
parser.add_option("-f", attr=value, ...)А чтобы определить параметр только с длинной строкой:
parser.add_option("--foo", attr=value, ...)Именованные аргументы задают атрибуты нового объекта Option. Самый важный атрибут параметра —
action; он во многом определяет, какие другие атрибуты имеют значение или являются обязательными. Если передать не относящиеся к параметру атрибуты или не передать обязательные,optparseвызовет исключениеOptionErrorс объяснением ошибки.Действие параметра определяет, что делает
optparse, когда встречает этот параметр в командной строке. Вoptparseжестко заданы следующие стандартные действия параметров:-
"store" -
сохранить аргумент этого параметра (по умолчанию)
-
"store_const" -
сохранить постоянное значение, предварительно заданное через
Option.const -
"store_true" -
сохранить
True -
"store_false" -
сохранить
False -
"append" -
добавить аргумент этого параметра в список
-
"append_const" -
добавить постоянное значение в список; оно предварительно задается через
Option.const -
"count" -
увеличить счетчик на единицу
-
"callback" -
вызвать указанную функцию
-
"help" -
вывести сообщение об использовании со всеми параметрами и их описаниями
(Если действие не задано, по умолчанию используется
"store". Для этого действия также можно задать атрибуты параметраtypeиdest; см. раздел Стандартные действия параметров.) -
Как видите, большинство действий подразумевает сохранение или изменение значения в каком-либо месте. Для этого optparse всегда создает специальный объект, обычно называемый options, который является экземпляром optparse.Values.
-
class optparse.Values -
Объект, хранящий разобранные имена и значения аргументов в виде атрибутов. Обычно создается при вызове
OptionParser.parse_args(); его можно переопределить пользовательским подклассом, переданным в аргумент values методаOptionParser.parse_args()(как описано в разделе Разбор аргументов).
Аргументы параметров (и различные другие значения) сохраняются в качестве атрибутов этого объекта в соответствии с атрибутом параметра dest (назначение).
Например, при вызове
parser.parse_args()
одно из первых действий optparse — создание объекта options:
options = Values()
Если один из параметров этого парсера определен так:
parser.add_option("-f", "--file", action="store", type="string", dest="filename")
и разбираемая командная строка содержит любой из следующих вариантов:
-ffoo -f foo --file=foo --file foo
то, встретив этот параметр, optparse выполнит эквивалент следующего действия:
options.filename = "foo"
Атрибуты параметра type и dest почти так же важны, как action, но только action имеет смысл для всех параметров.
Атрибуты параметров
-
class optparse.Option -
Отдельный аргумент командной строки с различными атрибутами, передаваемыми конструктору в виде именованных аргументов. Обычно создается с помощью
OptionParser.add_option(), а не напрямую; его можно переопределить пользовательским классом, переданным в аргументе option_class конструктораOptionParser.
Следующие атрибуты параметров можно передать в качестве именованных аргументов методу OptionParser.add_option(). Если передать атрибут параметра, не относящийся к этому параметру, или не передать обязательный атрибут, optparse вызовет исключение OptionError.
-
Option.action -
(по умолчанию:
"store")Определяет поведение
optparseпри обнаружении этого параметра в командной строке; доступные варианты описаны здесь.
-
Option.type -
(по умолчанию:
"string")Ожидаемый тип аргумента этого параметра (например,
"string"или"int"); доступные типы параметров описаны здесь.
-
Option.dest -
(по умолчанию: определяется по строкам параметров)
Если действие параметра подразумевает запись или изменение значения, этот атрибут указывает
optparse, куда его записать:destзадает имя атрибута объектаoptions, которыйoptparseсоздает при разборе командной строки.
-
Option.default -
Значение, используемое для назначения этого параметра, если параметр отсутствует в командной строке. См. также
OptionParser.set_defaults().
-
Option.nargs -
(по умолчанию: 1)
Количество аргументов типа
type, которые нужно обработать при обнаружении этого параметра. Если значение больше 1,optparseсохранит вdestкортеж значений.
-
Option.const -
Для действий, сохраняющих постоянное значение, — значение, которое нужно сохранить.
-
Option.choices -
Для параметров типа
"choice"— список строк, из которых пользователь может выбрать.
-
Option.callback -
Для параметров с действием
"callback"— вызываемый объект, который нужно вызвать при обнаружении этого параметра. Подробнее об аргументах, передаваемых вызываемому объекту, см. в разделе Обратные вызовы параметров.
-
Option.callback_args -
Option.callback_kwargs -
Дополнительные позиционные и именованные аргументы, передаваемые в
callbackпосле четырех стандартных аргументов обратного вызова.
-
Option.help -
Текст справки, выводимый для этого параметра при перечислении всех доступных параметров после того, как пользователь укажет параметр
help(например,--help). Если текст справки не задан, параметр будет выведен без описания. Чтобы скрыть этот параметр, используйте специальное значениеoptparse.SUPPRESS_HELP.
-
Option.metavar -
(по умолчанию: определяется по строкам параметров)
Заменитель аргумента(ов) параметра, используемый при выводе текста справки. Пример см. в разделе Руководство.
Стандартные действия параметров
Различные действия параметров имеют несколько отличающиеся требования и эффекты. У большинства действий есть несколько относящихся к ним атрибутов параметров, которые можно указать, чтобы задать поведение optparse; для некоторых действий требуются определённые атрибуты, которые необходимо указать для любого параметра, использующего это действие.
-
"store"[относящиеся атрибуты:type,dest,nargs,choices]За параметром должен следовать аргумент, который преобразуется в значение в соответствии с
typeи сохраняется вdest. Еслиnargs> 1, из командной строки будет извлечено несколько аргументов; все они будут преобразованы в соответствии сtypeи сохранены вdestв виде кортежа. См. раздел Стандартные типы параметров.Если указан
choices(список или кортеж строк), типом по умолчанию становится"choice".Если
typeне указан, по умолчанию используется"string".Если
destне указан,optparseвыводит имя назначения из первой длинной строки параметра (например,--foo-barподразумеваетfoo_bar). Если длинных строк параметров нет,optparseвыводит имя назначения из первой короткой строки параметра (например,-fподразумеваетf).Пример:
parser.add_option("-f") parser.add_option("-p", type="float", nargs=3, dest="point")При разборе командной строки
-f foo.txt -p 1 -3.5 4 -fbar.txt
optparseустановитoptions.f = "foo.txt" options.point = (1.0, -3.5, 4.0) options.f = "bar.txt"
-
"store_const"[обязательный атрибут:const; относящийся атрибут:dest]Значение
constсохраняется вdest.Пример:
parser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbose") parser.add_option("-v", "--verbose", action="store_const", const=1, dest="verbose") parser.add_option("--noisy", action="store_const", const=2, dest="verbose")Если встречается
--noisy,optparseустановитoptions.verbose = 2
-
"store_true"[относящийся атрибут:dest]Особый случай
"store_const", который сохраняетTrueвdest. -
"store_false"[относящийся атрибут:dest]Как
"store_true", но сохраняетFalse.Пример:
parser.add_option("--clobber", action="store_true", dest="clobber") parser.add_option("--no-clobber", action="store_false", dest="clobber") -
"append"[относящиеся атрибуты:type,dest,nargs,choices]За параметром должен следовать аргумент, который добавляется в список в
dest. Если дляdestне указано значение по умолчанию, пустой список создаётся автоматически при первом обнаружении этого параметра в командной строке модулемoptparse. Еслиnargs> 1, извлекается несколько аргументов, а вdestдобавляется кортеж длинойnargs.Значения по умолчанию для
typeиdestтакие же, как для действия"store".Пример:
parser.add_option("-t", "--tracks", action="append", type="int")Если в командной строке встречается
-t3,optparseвыполняет эквивалент следующего:options.tracks = [] options.tracks.append(int("3"))Если немного позже встречается
--tracks=4, выполняется:options.tracks.append(int("4"))Действие
appendвызывает методappendдля текущего значения параметра. Это означает, что для любого указанного значения по умолчанию должен существовать методappend. Кроме того, если значение по умолчанию не пустое, элементы по умолчанию будут присутствовать в разобранном значении параметра, а значения из командной строки будут добавлены после них:>>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults']) >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg']) >>> opts.files ['~/.mypkg/defaults', 'overrides.mypkg'] -
"append_const"[обязательный атрибут:const; относящийся атрибут:dest]Как
"store_const", но значениеconstдобавляется вdest; как и для"append", значениеdestпо умолчанию равноNone, а пустой список автоматически создаётся при первом обнаружении параметра. -
"count"[относящийся атрибут:dest]Увеличивает на единицу целое число, сохранённое в
dest. Если значение по умолчанию не указано, перед первым увеличением дляdestустанавливается значение 0.Пример:
parser.add_option("-v", action="count", dest="verbosity")При первом появлении
-vв командной строкеoptparseвыполняет эквивалент следующего:options.verbosity = 0 options.verbosity += 1
При каждом последующем появлении
-vвыполняетсяoptions.verbosity += 1
-
"callback"[обязательный атрибут:callback; относящиеся атрибуты:type,nargs,callback_args,callback_kwargs]Вызывает функцию, указанную в
callback, следующим образом:func(option, opt_str, value, parser, *args, **kwargs)
Дополнительные сведения см. в разделе Обратные вызовы параметров.
-
"help"Выводит полное справочное сообщение со всеми параметрами текущего анализатора параметров. Справочное сообщение формируется из строки
usage, переданной конструктору OptionParser, и строкиhelp, переданной каждому параметру.Если для параметра не указана строка
help, он всё равно будет включён в справочное сообщение. Чтобы полностью исключить параметр, используйте специальное значениеoptparse.SUPPRESS_HELP.optparseавтоматически добавляет параметрhelpко всем OptionParser, поэтому обычно создавать его не нужно.Пример:
from optparse import OptionParser, SUPPRESS_HELP # usually, a help option is added automatically, but that can # be suppressed using the add_help_option argument parser = OptionParser(add_help_option=False) parser.add_option("-h", "--help", action="help") parser.add_option("-v", action="store_true", dest="verbose", help="Be moderately verbose") parser.add_option("--file", dest="filename", help="Input file to read data from") parser.add_option("--secret", help=SUPPRESS_HELP)Если
optparseобнаружит в командной строке-hили--help, он выведет в stdout примерно такое справочное сообщение (при условии, чтоsys.argv[0]равно"foo.py"):Usage: foo.py [options] Options: -h, --help Show this help message and exit -v Be moderately verbose --file=FILENAME Input file to read data from
После вывода справочного сообщения
optparseзавершит процесс с кодомsys.exit(0). -
"version"Выводит номер версии, заданный для OptionParser, в stdout и завершает работу. Номер версии форматируется и выводится методом
print_version()класса OptionParser. Обычно это действие имеет смысл только в том случае, если конструктору OptionParser передан аргументversion. Как и параметрыhelp, параметрыversionобычно не создают, посколькуoptparseавтоматически добавляет их при необходимости.
Стандартные типы параметров
У optparse есть пять встроенных типов параметров: "string", "int", "choice", "float" и "complex". Если нужно добавить новые типы параметров, см. раздел Расширение optparse.
Аргументы строковых параметров никак не проверяются и не преобразуются: текст из командной строки сохраняется в назначении (или передаётся обратному вызову) без изменений.
Целочисленные аргументы (тип "int") разбираются следующим образом:
- если число начинается с
0x, оно разбирается как шестнадцатеричное - если число начинается с
0, оно разбирается как восьмеричное - если число начинается с
0b, оно разбирается как двоичное - в остальных случаях число разбирается как десятичное
Преобразование выполняется вызовом int() с соответствующим основанием (2, 8, 10 или 16). Если преобразование завершается ошибкой, то и optparse завершится ошибкой, но с более понятным сообщением.
Аргументы параметров "float" и "complex" преобразуются напрямую с помощью float() и complex() с аналогичной обработкой ошибок.
Параметры "choice" являются подтипом параметров "string". Атрибут параметра choices (последовательность строк) определяет набор допустимых аргументов параметра. optparse.check_choice() сравнивает аргументы параметра, заданные пользователем, с этим основным списком и вызывает OptionValueError, если указана недопустимая строка.
Разбор аргументов
Основная цель создания и заполнения OptionParser — вызов его метода parse_args().
-
OptionParser.parse_args(args=None, values=None) -
Разбирает параметры командной строки, указанные в args.
Входные параметры:
-
args -
список аргументов для обработки (по умолчанию:
sys.argv[1:]) -
values -
объект
Valuesдля хранения аргументов параметров (по умолчанию: новый экземплярValues) — если передать существующий объект, значения параметров по умолчанию для него инициализированы не будут
Возвращаемое значение — пара
(options, args), где:-
options -
тот же объект, который был передан в качестве values, либо экземпляр
optparse.Values, созданный модулемoptparse -
args -
оставшиеся позиционные аргументы после обработки всех параметров
-
Чаще всего оба именованных аргумента не передаются. Если передать values, он будет изменён вызовами setattr() (примерно по одному вызову для каждого аргумента параметра, сохранённого в назначении параметра) и возвращён методом parse_args().
Если parse_args() обнаружит ошибки в списке аргументов, он вызовет метод OptionParser error() с подходящим сообщением об ошибке для пользователя. В конечном итоге процесс завершится с кодом 2 (традиционный код завершения Unix для ошибок командной строки).
Запрос сведений об анализаторе параметров и управление им
Поведение анализатора параметров по умолчанию можно немного настроить; кроме того, можно изучить содержимое анализатора параметров. В OptionParser есть несколько полезных методов:
-
OptionParser.disable_interspersed_args() -
Задаёт остановку разбора на первом аргументе, не являющемся параметром. Например, если
-aи-b— простые параметры, не принимающие аргументов,optparseобычно принимает такой синтаксис:prog -a arg1 -b arg2
и обрабатывает его так же, как
prog -a -b arg1 arg2
Чтобы отключить эту возможность, вызовите
disable_interspersed_args(). Это возвращает традиционный синтаксис Unix, при котором разбор параметров прекращается на первом аргументе, не являющемся параметром.Используйте этот метод, если у вас есть обработчик команд, который запускает другую команду с собственными параметрами, и вы хотите избежать их смешения. Например, у каждой команды может быть свой набор параметров.
-
OptionParser.enable_interspersed_args() -
Задаёт продолжение разбора после первого аргумента, не являющегося параметром, позволяя перемежать параметры с аргументами команды. Это поведение используется по умолчанию.
-
OptionParser.get_option(opt_str) -
Возвращает экземпляр Option для строки параметра opt_str или
None, если такой строки нет ни у одного параметра.
-
OptionParser.has_option(opt_str) -
Возвращает
True, если у OptionParser есть параметр со строкой opt_str (например,-qили--verbose).
-
OptionParser.remove_option(opt_str) -
Если у
OptionParserесть параметр, соответствующий opt_str, этот параметр удаляется. Если у него были другие строки параметров, все они становятся недействительными. Если opt_str не встречается ни у одного параметра данногоOptionParser, вызывается исключениеValueError.
Конфликты между параметрами
Если быть невнимательным, легко определить параметры с конфликтующими строками:
parser.add_option("-n", "--dry-run", ...)
...
parser.add_option("-n", "--noisy", ...)
(Это особенно часто случается, если вы создали собственный подкласс OptionParser с набором стандартных параметров.)
При каждом добавлении параметра optparse проверяет его на конфликты с существующими параметрами. Если конфликт обнаружен, вызывается текущий механизм обработки конфликтов. Этот механизм можно задать в конструкторе:
parser = OptionParser(..., conflict_handler=handler)
или отдельным вызовом:
parser.set_conflict_handler(handler)
Доступны следующие обработчики конфликтов:
-
"error" (default) -
считать конфликты параметров ошибкой программирования и вызывать исключение
OptionConflictError -
"resolve" -
интеллектуально разрешать конфликты параметров (см. ниже)
Например, создадим OptionParser, который интеллектуально разрешает конфликты, и добавим в него конфликтующие параметры:
parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="do no harm")
parser.add_option("-n", "--noisy", ..., help="be noisy")
На этом этапе optparse обнаруживает, что строка параметра -n уже используется ранее добавленным параметром. Поскольку conflict_handler равно "resolve", конфликт разрешается удалением -n из списка строк параметров более раннего параметра. Теперь единственный способ активировать этот параметр — --dry-run. Если пользователь запросит справку, в сообщении будет отражено это изменение:
Options: --dry-run do no harm ... -n, --noisy be noisy
Можно постепенно удалить все строки параметров у ранее добавленного параметра, из-за чего у пользователя не останется способа вызвать его из командной строки. В этом случае optparse полностью удаляет этот параметр, чтобы он не отображался в справке и других местах. Продолжим работу с уже созданным OptionParser:
parser.add_option("--dry-run", ..., help="new dry-run option")
На этом этапе исходный параметр -n/--dry-run больше недоступен, поэтому optparse удаляет его, оставляя следующий текст справки:
Options: ... -n, --noisy be noisy --dry-run new dry-run option
Очистка
Экземпляры OptionParser содержат несколько циклических ссылок. Сборщик мусора Python должен корректно обработать их, однако при желании можно явно разорвать циклические ссылки, вызвав destroy() для OptionParser после завершения работы с ним. Это особенно полезно в долго работающих приложениях, где с OptionParser связаны большие графы объектов.
Другие методы
В OptionParser есть несколько других общедоступных методов:
-
OptionParser.set_usage(usage) -
Задаёт строку использования по правилам, описанным выше для именованного аргумента конструктора
usage. ПередачаNoneзадаёт строку использования по умолчанию; используйтеoptparse.SUPPRESS_USAGE, чтобы подавить вывод сообщения об использовании.
-
OptionParser.print_usage(file=None) -
Выводит сообщение об использовании текущей программы (
self.usage) в file (по умолчанию — stdout). Все вхождения строки%progвself.usageзаменяются именем текущей программы. Ничего не делает, еслиself.usageпуста или не определена.
-
OptionParser.get_usage() -
То же, что и
print_usage(), но возвращает строку использования, а не выводит её.
-
OptionParser.set_defaults(dest=value, ...) -
Одновременно задаёт значения по умолчанию для нескольких назначений параметров. Использование
set_defaults()— предпочтительный способ задать значения по умолчанию для параметров, поскольку несколько параметров могут иметь одно назначение. Например, если несколько параметров «режима» задают одно назначение, значение по умолчанию может задать любой из них, а при конфликте используется последнее:parser.add_option("--advanced", action="store_const", dest="mode", const="advanced", default="novice") # overridden below parser.add_option("--novice", action="store_const", dest="mode", const="novice", default="advanced") # overrides above settingЧтобы избежать этой неоднозначности, используйте
set_defaults():parser.set_defaults(mode="advanced") parser.add_option("--advanced", action="store_const", dest="mode", const="advanced") parser.add_option("--novice", action="store_const", dest="mode", const="novice")
Функции обратного вызова параметров
Когда встроенных действий и типов optparse недостаточно для ваших задач, есть два варианта: расширить optparse или определить параметр с функцией обратного вызова. Расширение optparse — более универсальный подход, но во многих простых случаях он избыточен. Часто достаточно простой функции обратного вызова.
Чтобы определить параметр с функцией обратного вызова, нужно выполнить два шага:
- определить сам параметр с помощью действия
"callback" - написать функцию обратного вызова; это функция (или метод), принимающая как минимум четыре аргумента, описанные ниже
Определение параметра с функцией обратного вызова
Как всегда, проще всего определить параметр с функцией обратного вызова с помощью метода OptionParser.add_option(). Помимо action, необходимо указать только один атрибут параметра — callback, вызываемую функцию:
parser.add_option("-c", action="callback", callback=my_callback)
callback — это функция (или другой вызываемый объект), поэтому к моменту создания параметра с этой функцией обратного вызова my_callback() уже должна быть определена. В этом простом случае optparse даже не знает, принимает ли -c какие-либо аргументы. Обычно это означает, что параметр не принимает аргументов: достаточно самого наличия -c в командной строке. Однако в некоторых случаях вы можете захотеть, чтобы функция обратного вызова обрабатывала произвольное число аргументов командной строки. В этом случае написание функций обратного вызова становится сложнее; об этом рассказано далее в этом разделе.
optparse всегда передаёт вашей функции обратного вызова четыре определённых аргумента и передаёт дополнительные аргументы, только если вы укажете их с помощью callback_args и callback_kwargs. Таким образом, минимальная сигнатура функции обратного вызова выглядит так:
def my_callback(option, opt, value, parser):
Четыре аргумента функции обратного вызова описаны ниже.
При определении параметра с функцией обратного вызова можно указать и несколько других атрибутов параметра:
-
type -
имеет обычное значение: как и для действий
"store"или"append", он указываетoptparseпринять один аргумент и преобразовать его к типуtype. Однако вместо сохранения преобразованных значений где-либоoptparseпередаёт их вашей функции обратного вызова. -
nargs -
тоже имеет обычное значение: если атрибут задан и его значение > 1,
optparseприметnargsаргументов, каждый из которых должен преобразовываться к типуtype. Затем функции обратного вызова передаётся кортеж преобразованных значений. -
callback_args -
кортеж дополнительных позиционных аргументов, передаваемых функции обратного вызова
-
callback_kwargs -
словарь дополнительных именованных аргументов, передаваемых функции обратного вызова
Вызов функций обратного вызова
Все функции обратного вызова вызываются следующим образом:
func(option, opt_str, value, parser, *args, **kwargs)
где
-
option -
экземпляр Option, вызывающий функцию обратного вызова
-
opt_str -
строка параметра из командной строки, вызвавшая функцию обратного вызова. (Если использовался сокращённый длинный параметр,
opt_strбудет полной канонической строкой параметра: например, если пользователь укажет в командной строке--fooкак сокращение для--foobar, тоopt_strбудет равно"--foobar".) -
value -
аргумент этого параметра из командной строки.
optparseожидает аргумент только в том случае, если заданtype; типvalueбудет определяться типом параметра. Если для этого параметраtypeравенNone(аргумент не ожидается), тоvalueбудет равенNone. Еслиnargs> 1,valueбудет кортежем значений соответствующего типа. -
parser -
экземпляр OptionParser, управляющий всем процессом. Он особенно полезен тем, что через его атрибуты экземпляра можно получить доступ к другим интересным данным:
-
parser.largs -
текущий список оставшихся аргументов, то есть аргументов, которые были обработаны, но не являются ни параметрами, ни аргументами параметров. Вы можете изменять
parser.largs, например добавлять в него другие аргументы. (Этот список станетargs— вторым возвращаемым значениемparse_args().) -
parser.rargs -
текущий список оставшихся аргументов: из него удалены
opt_strиvalue(если применимо), и в нём остаются только аргументы, следующие за ними. Вы можете изменятьparser.rargs, например обрабатывать дополнительные аргументы. -
parser.values -
объект, в котором по умолчанию хранятся значения параметров (экземпляр optparse.OptionValues). Благодаря этому функции обратного вызова могут использовать тот же механизм хранения значений параметров, что и остальные части
optparse; вам не нужно возиться с глобальными переменными или замыканиями. Вы также можете получать доступ к значениям любых параметров, уже встречавшихся в командной строке, и изменять их.
-
-
args -
кортеж произвольных позиционных аргументов, переданных через атрибут параметра
callback_args. -
kwargs -
словарь произвольных именованных аргументов, переданных через
callback_kwargs.
Возбуждение исключений в функции обратного вызова
Если возникли проблемы с параметром или его аргументами, функция обратного вызова должна возбуждать исключение OptionValueError. optparse перехватывает это исключение и завершает программу, выводя указанное вами сообщение об ошибке в stderr. Сообщение должно быть ясным, кратким и точным, а также указывать проблемный параметр. Иначе пользователю будет трудно понять, что он сделал не так.
Пример функции обратного вызова 1: простейшая функция
Вот пример параметра с функцией обратного вызова, который не принимает аргументов и просто фиксирует факт наличия параметра:
def record_foo_seen(option, opt_str, value, parser):
parser.values.saw_foo = True
parser.add_option("--foo", action="callback", callback=record_foo_seen)
Разумеется, то же самое можно сделать с помощью действия "store_true".
Пример функции обратного вызова 2: проверка порядка параметров
Вот немного более интересный пример: зафиксировать факт появления -a, но завершить выполнение с ошибкой, если он стоит в командной строке после -b.
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use -a after -b")
parser.values.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")
Пример функции обратного вызова 3: проверка порядка параметров (обобщённый вариант)
Если вы хотите повторно использовать эту функцию обратного вызова для нескольких похожих параметров (устанавливать флаг, но завершать выполнение с ошибкой, если -b уже встречался), потребуется немного доработать её: сообщение об ошибке и устанавливаемый флаг должны быть обобщёнными.
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use %s after -b" % opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')
Пример функции обратного вызова 4: проверка произвольного условия
Разумеется, условие может быть любым — проверять значения уже определённых параметров необязательно. Например, если у вас есть параметры, которые нельзя использовать в полнолуние, достаточно сделать следующее:
def check_moon(option, opt_str, value, parser):
if is_moon_full():
raise OptionValueError("%s option invalid when moon is full"
% opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("--foo",
action="callback", callback=check_moon, dest="foo")
(Определение is_moon_full() оставляется читателю в качестве упражнения.)
Пример функции обратного вызова 5: фиксированное число аргументов
Определение параметров с функциями обратного вызова, принимающих фиксированное число аргументов, немного усложняет задачу. Указание аргументов для такого параметра аналогично определению параметра "store" или "append": если определить type, параметр принимает один аргумент, который должен преобразовываться к этому типу; если дополнительно определить nargs, параметр принимает nargs аргументов.
Вот пример, который просто имитирует стандартное действие "store":
def store_value(option, opt_str, value, parser):
setattr(parser.values, option.dest, value)
...
parser.add_option("--foo",
action="callback", callback=store_value,
type="int", nargs=3, dest="foo")
Обратите внимание: optparse самостоятельно обрабатывает 3 аргумента и преобразует их в целые числа; вам остаётся только сохранить их. (Или сделать что-то другое; разумеется, для этого примера функция обратного вызова не нужна.)
Пример функции обратного вызова 6: переменное число аргументов
Задача усложняется, если параметр должен принимать переменное число аргументов. В этом случае необходимо написать функцию обратного вызова, поскольку optparse не предоставляет для этого встроенных возможностей. Кроме того, нужно учитывать некоторые тонкости традиционного разбора командной строки Unix, с которыми optparse обычно справляется самостоятельно. В частности, функции обратного вызова должны реализовывать общепринятые правила обработки отдельных аргументов -- и -:
- аргументами параметров могут быть как
--, так и- - отдельный
--(если он не является аргументом какого-либо параметра): прекратить обработку командной строки и отбросить-- - отдельный
-(если он не является аргументом какого-либо параметра): прекратить обработку командной строки, но сохранить-(добавить его вparser.largs)
Если параметр должен принимать переменное число аргументов, необходимо учесть несколько тонких и непростых вопросов. Конкретная реализация зависит от компромиссов, на которые вы готовы пойти в своём приложении (поэтому optparse напрямую не поддерживает такую функциональность).
Тем не менее вот пример функции обратного вызова для параметра с переменным числом аргументов:
def vararg_callback(option, opt_str, value, parser):
assert value is None
value = []
def floatable(str):
try:
float(str)
return True
except ValueError:
return False
for arg in parser.rargs:
# stop on --foo like options
if arg[:2] == "--" and len(arg) > 2:
break
# stop on -a, but not on -3 or -3.0
if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
break
value.append(arg)
del parser.rargs[:len(value)]
setattr(parser.values, option.dest, value)
...
parser.add_option("-c", "--callback", dest="vararg_attr",
action="callback", callback=vararg_callback)
Расширение optparse
Поскольку интерпретация параметров командной строки в optparse определяется прежде всего действием и типом каждого параметра, наиболее очевидный способ расширения — добавление новых действий и типов.
Добавление новых типов
Чтобы добавить новые типы, нужно определить собственный подкласс класса optparse Option. У этого класса есть несколько атрибутов, задающих типы optparse: TYPES и TYPE_CHECKER.
-
Option.TYPES -
Кортеж имён типов; в своём подклассе просто определите новый кортеж
TYPES, дополняющий стандартный.
-
Option.TYPE_CHECKER -
Словарь, сопоставляющий имена типов функциям проверки типов. Функция проверки типа имеет следующую сигнатуру:
def check_mytype(option, opt, value)
где
option— экземплярOption,opt— строка параметра (например,-f), аvalue— строка из командной строки, которую нужно проверить и преобразовать к требуемому типу.check_mytype()должна возвращать объект предполагаемого типаmytype. Значение, возвращённое функцией проверки типа, будет сохранено в экземпляре OptionValues, возвращаемом методомOptionParser.parse_args(), либо передано функции обратного вызова как параметрvalue.Если функция проверки типа обнаружит проблему, она должна возбудить исключение
OptionValueError. ИсключениеOptionValueErrorпринимает один строковый аргумент, который без изменений передаётся методуerror()классаOptionParser. Этот метод добавляет в начало имя программы и строку"error:", выводит всё это в stderr и завершает процесс.
Вот шуточный пример, показывающий, как добавить тип параметра "complex" для разбора комплексных чисел в стиле Python в командной строке. (Сейчас этот пример ещё нелепее, чем раньше, поскольку в версии 1.3 optparse появилась встроенная поддержка комплексных чисел, но неважно.)
Сначала необходимые импорты:
from copy import copy from optparse import Option, OptionValueError
Сначала нужно определить функцию проверки типа, поскольку далее на неё будет ссылка (в атрибуте класса TYPE_CHECKER вашего подкласса Option):
def check_complex(option, opt, value):
try:
return complex(value)
except ValueError:
raise OptionValueError(
"option %s: invalid complex value: %r" % (opt, value))
Наконец, подкласс Option:
class MyOption (Option):
TYPES = Option.TYPES + ("complex",)
TYPE_CHECKER = copy(Option.TYPE_CHECKER)
TYPE_CHECKER["complex"] = check_complex
(Если бы мы не создали copy() для Option.TYPE_CHECKER, мы изменили бы атрибут TYPE_CHECKER класса Option в optparse. Это Python, и от подобного вас удерживают только хорошие манеры и здравый смысл.)
Готово! Теперь можно написать скрипт, использующий новый тип параметра, как и любой другой скрипт на основе optparse. Единственное отличие — нужно указать OptionParser использовать MyOption вместо Option:
parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")
Другой вариант — создать собственный список параметров и передать его в OptionParser; если не использовать add_option() описанным выше способом, сообщать OptionParser, какой класс параметров использовать, не потребуется:
option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)
Добавление новых действий
Добавлять новые действия немного сложнее, поскольку нужно понимать, что в optparse действия классифицируются по нескольким признакам:
- Действия «сохранения»
-
действия, при которых
optparseсохраняет значение в атрибуте текущего экземпляра OptionValues; для таких параметров при создании Option необходимо указать атрибутdest. - Действия с типизированными значениями
-
действия, принимающие значение из командной строки и предполагающие, что оно имеет определённый тип; точнее, что строку можно преобразовать к определённому типу. Для таких параметров при создании Option необходимо указать атрибут
type.
Эти категории пересекаются: некоторые стандартные действия «сохранения» — это "store", "store_const", "append" и "count", а стандартные действия с типизированными значениями — это "store", "append" и "callback".
Добавляя действие, нужно отнести его к нужным категориям, указав его как минимум в одном из следующих атрибутов класса Option (все они представляют собой списки строк):
-
Option.ACTIONS -
Все действия должны быть перечислены в ACTIONS.
-
Option.STORE_ACTIONS -
Действия «сохранения» дополнительно перечисляются здесь.
-
Option.TYPED_ACTIONS -
Действия с типизированными значениями дополнительно перечисляются здесь.
-
Option.ALWAYS_TYPED_ACTIONS -
Здесь дополнительно перечисляются действия, всегда принимающие значение определённого типа (то есть их параметры всегда принимают значение). Единственный эффект этого списка — присвоение
optparseтипа по умолчанию"string"параметрам без явно заданного типа, действие которых перечислено вALWAYS_TYPED_ACTIONS.
Чтобы реализовать новое действие, необходимо переопределить метод take_action() класса Option и добавить в него обработку нового действия.
Например, добавим действие "extend". Оно похоже на стандартное действие "append", но вместо получения одного значения из командной строки и добавления его в существующий список действие "extend" принимает несколько значений в одной строке, разделённых запятыми, и добавляет их в существующий список. То есть если --names — это параметр "extend" типа "string", то при такой командной строке
--names=foo,bar --names blah --names ding,dong
получится список
["foo", "bar", "blah", "ding", "dong"]
Снова определим подкласс Option:
class MyOption(Option):
ACTIONS = Option.ACTIONS + ("extend",)
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
def take_action(self, action, dest, opt, value, values, parser):
if action == "extend":
lvalue = value.split(",")
values.ensure_value(dest, []).extend(lvalue)
else:
Option.take_action(
self, action, dest, opt, value, values, parser)
Обратите внимание на следующие особенности:
-
"extend"ожидает значение из командной строки и сохраняет его, поэтому это действие включено и вSTORE_ACTIONS, и вTYPED_ACTIONS. - Чтобы
optparseназначал действиям"extend"тип по умолчанию"string", мы также добавили действие"extend"вALWAYS_TYPED_ACTIONS. -
MyOption.take_action()реализует только это новое действие и передаёт управление обратно вOption.take_action()для обработки стандартных действийoptparse. -
values— экземпляр класса optparse_parser.Values, предоставляющего очень полезный методensure_value(). По сути,ensure_value()— этоgetattr()с дополнительной защитой; он вызывается так:values.ensure_value(attr, value)
Если атрибут
attrобъектаvaluesне существует или равенNone, ensure_value() сначала присваивает ему значениеvalue, а затем возвращаетvalue. Это очень удобно для таких действий, как"extend","append"и"count", каждое из которых накапливает данные в переменной и предполагает, что переменная имеет определённый тип (для первых двух — список, для последнего — целое число). Использованиеensure_value()избавляет скрипты, применяющие ваше действие, от необходимости задавать значение по умолчанию для соответствующих назначений параметров: достаточно оставить значение по умолчанию равнымNone, аensure_value()позаботится о том, чтобы при необходимости оно было правильным.
Исключения
-
exception optparse.OptionError -
Возбуждается при создании экземпляра
Optionс недопустимыми или противоречивыми аргументами.
-
exception optparse.OptionConflictError -
Возбуждается, если в
OptionParserдобавляются конфликтующие параметры.
-
exception optparse.OptionValueError -
Возбуждается при обнаружении недопустимого значения параметра в командной строке.
-
exception optparse.BadOptionError -
Возбуждается, если в командной строке передан недопустимый параметр.
-
exception optparse.AmbiguousOptionError -
Возбуждается, если в командной строке передан неоднозначный параметр.
© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/optparse.html