optparse.md
1> **Источник:** https://python-all.ru/3.1/library/optparse.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 15.4. `optparse` – более мощный парсер опций командной строки89`optparse` – это более удобная, гибкая и мощная библиотека для разбора опций командной строки, чем старый модуль [`getopt`](https://python-all.ru/3.1/library/getopt.html#module-getopt). `optparse` использует более декларативный стиль разбора командной строки: создаётся экземпляр [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser), заполняется опциями, и разбирается командная строка. `optparse` позволяет пользователям задавать опции в общепринятом синтаксисе GNU/POSIX, а также автоматически генерирует сообщения об использовании и справку.1011Вот пример использования `optparse` в простом скрипте:1213```python14from optparse import OptionParser15[...]16parser = OptionParser()17parser.add_option("-f", "--file", dest="filename",18 help="write report to FILE", metavar="FILE")19parser.add_option("-q", "--quiet",20 action="store_false", dest="verbose", default=True,21 help="don't print status messages to stdout")2223(options, args) = parser.parse_args()24```2526С помощью этих нескольких строк кода пользователи вашего скрипта теперь могут делать «обычные вещи» в командной строке, например:2728```python29<yourscript> --file=outfile -q30```3132При разборе командной строки `optparse` устанавливает атрибуты объекта `options`, возвращаемого функцией `parse_args()`, на основе введённых пользователем значений командной строки. Когда `parse_args()` завершает разбор этой командной строки, `options.filename` будет равен `"outfile"`, а `options.verbose` – `False`. `optparse` поддерживает как длинные, так и короткие опции, позволяет объединять короткие опции и связывать опции с их аргументами различными способами. Таким образом, все следующие командные строки эквивалентны приведённому выше примеру:3334```python35<yourscript> -f outfile --quiet36<yourscript> --quiet --file outfile37<yourscript> -q -foutfile38<yourscript> -qfoutfile39```4041Кроме того, можно запустить один из4243```python44<yourscript> -h45<yourscript> --help46```4748и `optparse` выведет краткую сводку опций вашего скрипта:4950```text51Usage: <yourscript> [options]5253Options:54 -h, --help show this help message and exit55 -f FILE, --file=FILE write report to FILE56 -q, --quiet don't print status messages to stdout57```5859где значение *yourscript* определяется во время выполнения (обычно из `sys.argv[0]`).6061## 15.4.1. Предыстория6263`optparse` был разработан специально для поощрения создания программ с простыми и общепринятыми интерфейсами командной строки. Для этого он поддерживает только наиболее распространённый синтаксис и семантику командной строки, традиционно используемые в Unix. Если вы не знакомы с этими соглашениями, прочтите этот раздел, чтобы ознакомиться с ними.6465### 15.4.1.1. Терминология6667**аргумент**6869строка, введённая в командной строке и переданная оболочкой в `execl()` или `execv()`. В Python аргументы являются элементами `sys.argv[1:]` (`sys.argv[0]` – это имя выполняемой программы). В оболочках Unix также используется термин «слово».7071Иногда требуется подставить список аргументов, отличный от `sys.argv[1:]`, поэтому следует понимать «аргумент» как «элемент `sys.argv[1:]` или какого-либо другого списка, предоставленного вместо `sys.argv[1:]`».7273**опция**7475аргумент, используемый для предоставления дополнительной информации, направляющей или настраивающей выполнение программы. Существует много разных синтаксисов для опций; традиционный синтаксис Unix – дефис («-»), за которым следует одна буква, например `-x` или `-F`. Кроме того, традиционный синтаксис Unix позволяет объединять несколько опций в один аргумент, например `-x -F` эквивалентно `-xF`. Проект GNU ввёл `--`, за которым следует серия слов, разделённых дефисами, например `--file` или `--dry-run`. Это единственные два синтаксиса опций, поддерживаемые `optparse`.7677Некоторые другие синтаксисы опций, которые встречались в мире, включают:7879- дефис, за которым следует несколько букв, например `-pf` (это *не* то же самое, что объединение нескольких опций в один аргумент)80- дефис, за которым следует целое слово, например `-file` (технически это эквивалентно предыдущему синтаксису, но они обычно не встречаются в одной программе)81- знак плюс, за которым следует одна буква, несколько букв или слово, например `+f`, `+rgb`82- косая черта, за которой следует буква, несколько букв или слово, например `/f`, `/file`8384Эти синтаксисы опций не поддерживаются `optparse` и никогда не будут. Это сделано намеренно: первые три нестандартны в любом окружении, а последний имеет смысл только при ориентации исключительно на VMS, MS-DOS и/или Windows.8586**аргумент опции**8788аргумент, который следует за опцией, тесно связан с ней и извлекается из списка аргументов вместе с этой опцией. В `optparse` аргументы опций могут находиться либо в отдельном аргументе от своей опции:8990```text91-f foo92--file foo93```9495или включены в тот же аргумент:9697```text98-ffoo99--file=foo100```101102Обычно конкретная опция либо принимает аргумент, либо нет. Многие хотят функцию «необязательных аргументов опции», означающую, что некоторые опции будут принимать аргумент, если его увидят, и не будут, если не увидят. Это довольно спорно, потому что делает разбор неоднозначным: если `-a` принимает необязательный аргумент, а `-b` – совершенно другая опция, как интерпретировать `-ab`? Из-за этой неоднозначности `optparse` не поддерживает такую возможность.103104**позиционный аргумент**105106то, что осталось в списке аргументов после разбора опций, т.е. после того, как опции и их аргументы были разобраны и удалены из списка аргументов.107108**обязательная опция**109110опция, которая обязательно должна быть указана в командной строке; обратите внимание, что фраза «обязательная опция» внутренне противоречива в английском языке.111112`optparse`113114не запрещает реализовывать обязательные опции, но и особо не помогает в этом.115116Например, рассмотрим эту гипотетическую командную строку:117118```python119prog -v --report /tmp/report.txt foo bar120```121122`-v` и `--report` – оба опции. Если допустить, что `--report` принимает один аргумент, то `/tmp/report.txt` – это аргумент опции. `foo` и `bar` – позиционные аргументы.123124### 15.4.1.2. Для чего нужны опции?125126Опции используются для предоставления дополнительной информации для настройки или кастомизации выполнения программы. На всякий случай, если это не было очевидно: опции обычно *необязательны*. Программа должна нормально работать вообще без опций. (Выберите случайную программу из набора Unix или GNU. Может ли она работать вообще без опций и при этом иметь смысл? Основные исключения – `find`, `tar` и `dd` – все они являются мутантными чудаками, которые справедливо критикуются за нестандартный синтаксис и запутанные интерфейсы.)127128Многие хотят, чтобы в их программах были «обязательные опции». Подумайте об этом. Если это обязательно, значит, это *не необязательно*! Если есть информация, которая absolutely необходима вашей программе для успешного выполнения, для этого существуют позиционные аргументы.129130В качестве примера хорошего дизайна интерфейса командной строки рассмотрим скромную утилиту `cp` для копирования файлов. Не имеет особого смысла пытаться копировать файлы без указания назначения и хотя бы одного источника. Следовательно, `cp` завершается ошибкой, если запустить её без аргументов. Однако у неё гибкий, полезный синтаксис, который вообще не требует никаких опций:131132```python133cp SOURCE DEST134cp SOURCE ... DEST-DIR135```136137С этим можно зайти довольно далеко. Большинство реализаций `cp` предоставляют множество опций для точной настройки копирования: можно сохранять режим и время изменения, избегать следования симлинкам, спрашивать подтверждение перед перезаписью существующих файлов и т.д. Но ничто из этого не отвлекает от основной миссии `cp`, которая состоит в копировании одного файла в другой или нескольких файлов в другой каталог.138139### 15.4.1.3. Для чего нужны позиционные аргументы?140141Позиционные аргументы предназначены для тех частей информации, которые absolutely и однозначно необходимы вашей программе для работы.142143Хороший пользовательский интерфейс должен иметь как можно меньше абсолютных требований. Если вашей программе требуется 17 различных частей информации для успешного запуска, не имеет большого значения *как* вы получаете эту информацию от пользователя – большинство людей сдадутся и уйдут, так и не запустив программу. Это справедливо независимо от того, является ли интерфейс командной строкой, файлом конфигурации или графическим интерфейсом: если вы предъявляете столько требований к пользователям, большинство из них просто сдадутся.144145Короче говоря, старайтесь минимизировать объем информации, которую пользователи absolutely обязаны предоставить – используйте разумные значения по умолчанию, когда это возможно. Конечно, вы также хотите сделать свои программы достаточно гибкими. Для этого и нужны опции. Опять же, неважно, являются ли они записями в файле конфигурации, виджетами в диалоге «Настройки» графического интерфейса или опциями командной строки – чем больше опций вы реализуете, тем гибче становится ваша программа, и тем сложнее становится ее реализация. Слишком большая гибкость тоже имеет недостатки; слишком много опций может перегрузить пользователей и сделать ваш код гораздо сложнее в поддержке.146147## 15.4.2. Руководство148149Хотя `optparse` довольно гибок и мощен, в большинстве случаев он достаточно прост в использовании. В этом разделе рассматриваются шаблоны кода, общие для любой программы на основе `optparse`.150151Сначала необходимо импортировать класс OptionParser; затем, в начале основной программы, создать экземпляр OptionParser:152153```python154from optparse import OptionParser155[...]156parser = OptionParser()157```158159Затем можно приступить к определению опций. Базовый синтаксис:160161```python162parser.add_option(opt_str, ...,163 attr=value, ...)164```165166Каждая опция имеет одну или несколько строк опций, таких как `-f` или `--file`, и несколько атрибутов опции, которые сообщают `optparse`, что ожидать и что делать при обнаружении этой опции в командной строке.167168Обычно каждая опция имеет одну короткую и одну длинную строку опции, например:169170```python171parser.add_option("-f", "--file", ...)172```173174Вы можете определить любое количество коротких и длинных строк опций (включая ноль), при условии, что в целом есть хотя бы одна строка опции.175176Строки опций, передаваемые в `add_option()`, по сути являются метками для опции, определённой этим вызовом. Для краткости мы часто будем говорить о *встрече опции* в командной строке; на самом деле `optparse` встречает *строки опций* и ищет по ним опции.177178Когда все опции определены, укажите `optparse` разобрать командную строку вашей программы:179180```python181(options, args) = parser.parse_args()182```183184(При желании можно передать собственный список аргументов в `parse_args()`, но это редко бывает необходимо: по умолчанию используется `sys.argv[1:]`.)185186`parse_args()` возвращает два значения:187188- `options` – объект, содержащий значения всех опций; например, если `--file` принимает один строковый аргумент, то `options.file` будет именем файла, указанным пользователем, или `None`, если пользователь не указал эту опцию.189- `args` – список позиционных аргументов, оставшихся после разбора опций.190191В этом разделе руководства рассматриваются только четыре наиболее важных атрибута опций: [`action`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.action), [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type), [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) (назначение) и [`help`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.help). Из них [`action`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.action) является самым основным.192193### 15.4.2.1. Понимание действий опций194195Действия сообщают `optparse`, что делать при обнаружении опции в командной строке. Существует фиксированный набор действий, встроенных в `optparse`; добавление новых действий – продвинутая тема, рассматриваемая в разделе [*Расширение optparse*](https://python-all.ru/3.1/library/optparse.html#optparse-extending-optparse). Большинство действий указывают `optparse` сохранить значение в некоторой переменной – например, взять строку из командной строки и сохранить её в атрибуте `options`.196197Если не указать действие опции, `optparse` по умолчанию использует `store`.198199### 15.4.2.2. Действие store200201Наиболее распространённое действие опции – `store`, которое указывает `optparse` взять следующий аргумент (или остаток текущего аргумента), убедиться, что он имеет правильный тип, и сохранить его в выбранное вами назначение.202203Например:204205```python206parser.add_option("-f", "--file",207 action="store", type="string", dest="filename")208```209210Теперь создадим фиктивную командную строку и попросим `optparse` разобрать её:211212```python213args = ["-f", "foo.txt"]214(options, args) = parser.parse_args(args)215```216217Когда `optparse` видит строку опции `-f`, он потребляет следующий аргумент, `foo.txt`, и сохраняет его в `options.filename`. Таким образом, после этого вызова `parse_args()`, `options.filename` равен `"foo.txt"`.218219Некоторые другие типы опций, поддерживаемые `optparse`: `int` и `float`. Вот опция, ожидающая целочисленный аргумент:220221```python222parser.add_option("-n", type="int", dest="num")223```224225Обратите внимание, что эта опция не имеет длинной строки опции, что вполне допустимо. Кроме того, нет явного действия, поскольку по умолчанию используется `store`.226227Разберём ещё одну фиктивную командную строку. На этот раз мы поместим аргумент опции непосредственно рядом с опцией: поскольку `-n42` (один аргумент) эквивалентно `-n 42` (два аргумента), код228229```python230(options, args) = parser.parse_args(["-n42"])231print(options.num)232```233234выведет `42`.235236Если не указать тип, `optparse` предполагает `string`. В сочетании с тем, что действие по умолчанию – `store`, это означает, что наш первый пример можно значительно сократить:237238```python239parser.add_option("-f", "--file", dest="filename")240```241242Если не указать назначение, `optparse` самостоятельно определяет разумное значение по умолчанию из строк параметров: если первая длинная строка параметра – `--foo-bar`, то назначение по умолчанию – `foo_bar`. Если длинных строк параметров нет, `optparse` берёт первую короткую строку параметра: назначение по умолчанию для `-f` – `f`.243244`optparse` также включает встроенный тип `complex`. Добавление типов описано в разделе [*Extending optparse*](https://python-all.ru/3.1/library/optparse.html#optparse-extending-optparse).245246### 15.4.2.3. Обработка булевых (флаговых) параметров247248Флаговые параметры – установка переменной в true или false при встрече определённого параметра – довольно распространены. `optparse` поддерживает их с помощью двух отдельных действий: `store_true` и `store_false`. Например, у вас может быть флаг `verbose`, который включается с помощью `-v` и выключается с помощью `-q`:249250```python251parser.add_option("-v", action="store_true", dest="verbose")252parser.add_option("-q", action="store_false", dest="verbose")253```254255Здесь у нас две разные опции с одним и тем же назначением, что совершенно нормально. (Это просто означает, что нужно быть немного внимательнее при установке значений по умолчанию – см. ниже.)256257Когда `optparse` встречает в командной строке `-v`, он устанавливает `options.verbose` в `True`; когда он встречает `-q`, `options.verbose` устанавливается в `False`.258259### 15.4.2.4. Другие действия260261Некоторые другие действия, поддерживаемые `optparse`:262263**`"store_const"`**264265сохранить константное значение266267**`"append"`**268269добавить аргумент этой опции в список270271**`"count"`**272273увеличить счётчик на единицу274275**`\"колбэк\"`**276277вызвать указанную функцию278279Эти вопросы рассматриваются в разделе [*Справочное руководство*](https://python-all.ru/3.1/library/optparse.html#optparse-reference-guide), Справочное руководство и разделе [*Колбэки опций*](https://python-all.ru/3.1/library/optparse.html#optparse-option-callbacks).280281### 15.4.2.5. Значения по умолчанию282283Все приведённые выше примеры подразумевают установку некоторой переменной (так называемого «назначения») при встрече определённых параметров командной строки. Что произойдёт, если эти параметры ни разу не встретятся? Поскольку мы не указали значения по умолчанию, все они будут установлены в `None`. Обычно это нормально, но иногда хочется большего контроля. `optparse` позволяет указать значение по умолчанию для каждого назначения; оно присваивается до разбора командной строки.284285Сначала рассмотрим пример с verbose/quiet. Если мы хотим, чтобы `optparse` устанавливал `verbose` в `True`, если только не встречен `-q`, то можно сделать так:286287```python288parser.add_option("-v", action="store_true", dest="verbose", default=True)289parser.add_option("-q", action="store_false", dest="verbose")290```291292Поскольку значения по умолчанию применяются к *назначению*, а не к какому-либо конкретному параметру, и эти два параметра имеют одно и то же назначение, это полностью эквивалентно:293294```python295parser.add_option("-v", action="store_true", dest="verbose")296parser.add_option("-q", action="store_false", dest="verbose", default=True)297```298299Рассмотрим это:300301```python302parser.add_option("-v", action="store_true", dest="verbose", default=False)303parser.add_option("-q", action="store_false", dest="verbose", default=True)304```305306Опять же, значение по умолчанию для `verbose` будет `True`: последнее значение по умолчанию, указанное для любого конкретного назначения, считается окончательным.307308Более понятный способ указать значения по умолчанию – метод `set_defaults()` класса OptionParser, который можно вызвать в любое время до вызова `parse_args()`:309310```python311parser.set_defaults(verbose=True)312parser.add_option(...)313(options, args) = parser.parse_args()314```315316Как и прежде, последнее указанное значение для данного назначения параметра и будет использоваться. Для ясности старайтесь использовать какой-то один способ задания значений по умолчанию, а не оба сразу.317318### 15.4.2.6. Генерация справки319320Возможность `optparse` автоматически генерировать текст справки и использования полезна для создания удобных интерфейсов командной строки. Всё, что нужно сделать, – указать значение [`help`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.help) для каждого параметра и, возможно, короткое сообщение об использовании для всей программы. Вот OptionParser, заполненный удобными (документированными) параметрами:321322```python323usage = "usage: %prog [options] arg1 arg2"324parser = OptionParser(usage=usage)325parser.add_option("-v", "--verbose",326 action="store_true", dest="verbose", default=True,327 help="make lots of noise [default]")328parser.add_option("-q", "--quiet",329 action="store_false", dest="verbose",330 help="be vewwy quiet (I'm hunting wabbits)")331parser.add_option("-f", "--filename",332 metavar="FILE", help="write output to FILE")333parser.add_option("-m", "--mode",334 default="intermediate",335 help="interaction mode: novice, intermediate, "336 "or expert [default: %default]")337```338339Если `optparse` встречает в командной строке `-h` или `--help`, или же просто вызвать `parser.print_help()`, он выводит следующее в стандартный вывод:340341```text342Usage: <yourscript> [options] arg1 arg2343344Options:345 -h, --help show this help message and exit346 -v, --verbose make lots of noise [default]347 -q, --quiet be vewwy quiet (I'm hunting wabbits)348 -f FILE, --filename=FILE349 write output to FILE350 -m MODE, --mode=MODE interaction mode: novice, intermediate, or351 expert [default: intermediate]352```353354(Если вывод справки вызван параметром помощи, `optparse` завершает работу после печати текста справки.)355356Здесь задействовано много всего, чтобы помочь `optparse` сгенерировать наилучшее сообщение справки:357358- сценарий определяет собственное сообщение об использовании:359360 ```python361 usage = "usage: %prog [options] arg1 arg2"362 ```363364 `optparse` заменяет `%prog` в строке использования на имя текущей программы, т.е. `os.path.basename(sys.argv[0])`. Затем развёрнутая строка выводится перед подробной справкой по параметрам.365366 Если не указать строку использования, `optparse` использует простое, но разумное значение по умолчанию: `"Usage: %prog [options]"`, что нормально, если ваш сценарий не принимает позиционных аргументов.367- каждый параметр определяет строку справки, и не нужно беспокоиться о переносе строк – `optparse` заботится о переносе строк и о том, чтобы вывод справки выглядел хорошо.368- Опции, принимающие значение, указывают на это в автоматически сгенерированном сообщении справки, например, для опции «mode»:369370 ```python371 -m MODE, --mode=MODE372 ```373374 Здесь «MODE» называется мета-переменной: она обозначает аргумент, который пользователь должен указать для `-m`/`--mode`. По умолчанию `optparse` преобразует имя переменной назначения в верхний регистр и использует его в качестве мета-переменной. Иногда это не то, что нужно – например, параметр `--filename` явно задаёт `metavar="FILE"`, что приводит к такому автоматически сгенерированному описанию параметра:375376 ```python377 -f FILE, --filename=FILE378 ```379380 Это важно не только для экономии места: написанный вручную текст справки использует мета-переменную `FILE`, чтобы подсказать пользователю, что существует связь между полуформальным синтаксисом `-f FILE` и неформальным семантическим описанием «write output to FILE». Это простой, но эффективный способ сделать текст справки гораздо понятнее и полезнее для конечных пользователей.381- параметры, имеющие значение по умолчанию, могут включать `%default` в строку справки – `optparse` заменит его на [`str()`](https://python-all.ru/3.1/library/functions.html#str) от значения по умолчанию параметра. Если у параметра нет значения по умолчанию (или значение по умолчанию – `None`), `%default` разворачивается в `none`.382383#### 15.4.2.6.1. Группировка параметров384385При работе с большим количеством параметров удобно группировать их для лучшего вывода справки. [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser) может содержать несколько групп параметров, каждая из которых может содержать несколько параметров.386387Группа параметров создается с помощью класса [`OptionGroup`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionGroup):388389#### `class optparse.OptionGroup(parser, title, description=None)`390391где392393- parser – это экземпляр [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser), в который будет вставлена группа.394- title – это заголовок группы395- description (необязательно) – это подробное описание группы396397[`OptionGroup`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionGroup) наследуется от `OptionContainer` (как и [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser)), поэтому метод `add_option()` можно использовать для добавления параметра в группу.398399После того как все параметры объявлены, группа добавляется в ранее определенный парсер с помощью метода [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser) – `add_option_group()`.400401Продолжая с парсером, определенным в предыдущем разделе, добавить [`OptionGroup`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionGroup) к парсеру легко:402403```python404group = OptionGroup(parser, "Dangerous Options",405 "Caution: use these options at your own risk. "406 "It is believed that some of them bite.")407group.add_option("-g", action="store_true", help="Group option.")408parser.add_option_group(group)409```410411Это приведёт к следующему выводу справки:412413```text414Usage: <yourscript> [options] arg1 arg2415416Options:417 -h, --help show this help message and exit418 -v, --verbose make lots of noise [default]419 -q, --quiet be vewwy quiet (I'm hunting wabbits)420 -f FILE, --filename=FILE421 write output to FILE422 -m MODE, --mode=MODE interaction mode: novice, intermediate, or423 expert [default: intermediate]424425 Dangerous Options:426 Caution: use these options at your own risk. It is believed that some427 of them bite.428429 -g Group option.430```431432Более полный пример может включать использование нескольких групп: продолжая предыдущий пример:433434```python435group = OptionGroup(parser, "Dangerous Options",436 "Caution: use these options at your own risk. "437 "It is believed that some of them bite.")438group.add_option("-g", action="store_true", help="Group option.")439parser.add_option_group(group)440441group = OptionGroup(parser, "Debug Options")442group.add_option("-d", "--debug", action="store_true",443 help="Print debug information")444group.add_option("-s", "--sql", action="store_true",445 help="Print all SQL statements executed")446group.add_option("-e", action="store_true", help="Print every action done")447parser.add_option_group(group)448```449450что приводит к следующему выводу:451452```text453Usage: <yourscript> [options] arg1 arg2454455Options:456 -h, --help show this help message and exit457 -v, --verbose make lots of noise [default]458 -q, --quiet be vewwy quiet (I'm hunting wabbits)459 -f FILE, --filename=FILE460 write output to FILE461 -m MODE, --mode=MODE interaction mode: novice, intermediate, or expert462 [default: intermediate]463464 Dangerous Options:465 Caution: use these options at your own risk. It is believed that some466 of them bite.467468 -g Group option.469470 Debug Options:471 -d, --debug Print debug information472 -s, --sql Print all SQL statements executed473 -e Print every action done474```475476Ещё один интересный метод, особенно при программной работе с группами опций:477478#### `OptionParser.get_option_group(opt_str)`479480Возвращает, если определена,481482[`OptionGroup`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionGroup)483484, заголовок или длинное описание которой равно485486*opt\_str*487488.489490### 15.4.2.7. Вывод строки версии491492Подобно краткой строке использования, `optparse` также может выводить строку версии для вашей программы. Нужно указать эту строку в качестве аргумента `version` для OptionParser:493494```python495parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")496```497498`%prog` разворачивается так же, как и в `usage`. Помимо этого, `version` может содержать что угодно. Когда вы его указываете, `optparse` автоматически добавляет параметр `--version` в ваш анализатор. Если он встречает этот параметр в командной строке, он разворачивает строку `version` (заменяя `%prog`), выводит её в stdout и завершает работу.499500Например, если ваш скрипт называется `/usr/bin/foo`:501502```python503$ /usr/bin/foo --version504foo 1.0505```506507Следующие два метода можно использовать для вывода и получения строки `version`:508509#### `OptionParser.print_version(file=None)`510511Выводит сообщение о версии текущей программы (512513`self.version`514515) в516517*file*518519(по умолчанию stdout). Как и в520521[`print_usage()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.print_usage)522523, любое вхождение524525`%prog`526527в528529`self.version`530531заменяется на имя текущей программы. Ничего не делает, если532533`self.version`534535пусто или не определено.536537#### `OptionParser.get_version()`538539То же, что и540541[`print_version()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.print_version)542543, но возвращает строку версии вместо её вывода.544545### 15.4.2.8. Как `optparse` обрабатывает ошибки546547Есть два основных класса ошибок, с которыми приходится иметь дело `optparse`: ошибки программиста и ошибки пользователя. Ошибки программиста – это обычно неверные вызовы [`OptionParser.add_option()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.add_option), например, недопустимые строки опций, неизвестные атрибуты опций, отсутствующие атрибуты опций и т.д. Они обрабатываются обычным способом: вызывается исключение (либо `optparse.OptionError`, либо [`TypeError`](https://python-all.ru/3.1/library/exceptions.html#TypeError)) и программа завершается с ошибкой.548549Обработка ошибок пользователя гораздо важнее, поскольку они неизбежно возникают независимо от того, насколько стабилен ваш код. `optparse` может автоматически обнаруживать некоторые ошибки пользователя, такие как неверные аргументы опций (передача `-n 4x`, где `-n` принимает целочисленный аргумент), отсутствие аргументов (`-n` в конце командной строки, где `-n` принимает аргумент любого типа). Также можно вызвать `OptionParser.error()` для сигнализации об ошибке, определённой приложением:550551```python552(options, args) = parser.parse_args()553[...]554if options.a and options.b:555 parser.error("options -a and -b are mutually exclusive")556```557558В любом случае `optparse` обрабатывает ошибку одинаково: выводит справку по использованию программы и сообщение об ошибке в стандартный поток ошибок и завершается с кодом ошибки 2.559560Рассмотрим первый пример выше, где пользователь передает `4x` параметру, который ожидает целое число:561562```python563$ /usr/bin/foo -n 4x564Usage: foo [options]565566foo: error: option -n: invalid integer value: '4x'567```568569Или когда пользователь вообще не передаёт значение:570571```python572$ /usr/bin/foo -n573Usage: foo [options]574575foo: error: -n option requires an argument576```577578Сообщения об ошибках, генерируемые `optparse`, всегда упоминают опцию, связанную с ошибкой; обязательно делайте то же самое при вызове `OptionParser.error()` из кода вашего приложения.579580Если поведение обработки ошибок по умолчанию `optparse` не подходит для ваших нужд, необходимо создать подкласс OptionParser и переопределить его методы `exit()` и/или `error()`.581582### 15.4.2.9. Собираем всё вместе583584Вот как обычно выглядят сценарии на основе `optparse`:585586```python587from optparse import OptionParser588[...]589def main():590 usage = "usage: %prog [options] arg"591 parser = OptionParser(usage)592 parser.add_option("-f", "--file", dest="filename",593 help="read data from FILENAME")594 parser.add_option("-v", "--verbose",595 action="store_true", dest="verbose")596 parser.add_option("-q", "--quiet",597 action="store_false", dest="verbose")598 [...]599 (options, args) = parser.parse_args()600 if len(args) != 1:601 parser.error("incorrect number of arguments")602 if options.verbose:603 print("reading %s..." % options.filename)604 [...]605606if __name__ == "__main__":607 main()608```609610## 15.4.3. Справочное руководство611612### 15.4.3.1. Создание парсера613614Первый шаг при использовании `optparse` – создание экземпляра OptionParser.615616#### `class optparse.OptionParser(...)`617618Конструктор OptionParser не требует обязательных аргументов, но принимает ряд необязательных именованных аргументов. Их всегда следует передавать как именованные аргументы, т.е. не полагаться на порядок объявления аргументов.619620**`usage` (по умолчанию: `"%prog [options]"`)**621622Краткая справка по использованию, выводимая при неправильном запуске программы или с опцией помощи. Когда623624`optparse`625626выводит строку использования, он заменяет627628`%prog`629630на631632`os.path.basename(sys.argv[0])`633634(или на635636`prog`637638, если был передан соответствующий именованный аргумент). Чтобы подавить сообщение об использовании, передайте специальное значение639640`optparse.SUPPRESS_USAGE`641642.643644**`option_list` (по умолчанию: `[]`)**645646Список объектов Option для заполнения парсера. Параметры из647648`option_list`649650добавляются после всех параметров из651652`standard_option_list`653654(атрибут класса, который может быть установлен подклассами OptionParser), но перед любыми параметрами версии или справки. Устарело; вместо этого используйте655656[`add_option()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.add_option)657658после создания парсера.659660**`option_class` (по умолчанию: optparse.Option)**661662Класс, используемый при добавлении опций в парсер с помощью663664[`add_option()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.add_option)665666.667668**`version` (по умолчанию: `None`)**669670Строка версии, выводимая, когда пользователь указывает опцию версии. Если передать истинное значение для671672`version`673674,675676`optparse`677678автоматически добавляет опцию версии с единственной строкой опции679680`--version`681682. Подстрока683684`%prog`685686раскрывается так же, как и для687688`usage`689690.691692**`conflict_handler` (по умолчанию: `"error"`)**693694Определяет, что делать, когда в парсер добавляются опции с конфликтующими строками опций; см. раздел695696[*Конфликты между опциями*](https://python-all.ru/3.1/library/optparse.html#optparse-conflicts-between-options)697698.699700**`description` (по умолчанию: `None`)**701702Абзац текста с кратким обзором программы.703704`optparse`705706переформатирует этот абзац под текущую ширину терминала и выводит его при запросе помощи (после707708`usage`709710, но до списка опций).711712**`formatter` (по умолчанию: новый `IndentedHelpFormatter`)**713714Экземпляр optparse.HelpFormatter, который будет использоваться для вывода справки.715716`optparse`717718предоставляет два конкретных класса для этой цели: IndentedHelpFormatter и TitledHelpFormatter.719720**`add_help_option` (по умолчанию: `True`)**721722Если истина,723724`optparse`725726добавит опцию помощи (со строками опции727728`-h`729730и731732`--help`733734) в парсер.735736**`prog`**737738Строка, используемая при раскрытии739740`%prog`741742в743744`usage`745746и747748`version`749750вместо751752`os.path.basename(sys.argv[0])`753754.755756**`epilog` (по умолчанию: `None`)**757758Абзац текста справки, выводимый после справки по опциям.759760### 15.4.3.2. Наполнение парсера761762Есть несколько способов наполнить парсер опциями. Предпочтительный – использовать [`OptionParser.add_option()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.add_option), как показано в разделе [*Tutorial*](https://python-all.ru/3.1/library/optparse.html#optparse-tutorial). `add_option()` можно вызывать одним из двух способов:763764- передать ему экземпляр Option (возвращаемый функцией `make_option()`)765- передать ему любую комбинацию позиционных и именованных аргументов, допустимых для `make_option()` (т.е. для конструктора Option), и он создаст экземпляр Option.766767Другой способ – передать список предварительно созданных экземпляров Option конструктору OptionParser, например:768769```python770option_list = [771 make_option("-f", "--filename",772 action="store", type="string", dest="filename"),773 make_option("-q", "--quiet",774 action="store_false", dest="verbose"),775 ]776parser = OptionParser(option_list=option_list)777```778779(`make_option()` – это фабричная функция для создания экземпляров Option; в настоящее время это псевдоним конструктора Option. Будущая версия `optparse` может разделить Option на несколько классов, и `make_option()` будет выбирать правильный класс для создания. Не создавайте экземпляры Option напрямую.)780781### 15.4.3.3. Определение опций782783Каждый экземпляр Option представляет набор синонимичных строк опций командной строки, например `-f` и `--file`. Можно указать любое количество коротких или длинных строк опций, но необходимо указать хотя бы одну общую строку опции.784785Канонический способ создания экземпляра `Option` – использовать метод `add_option()` класса [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser).786787#### `OptionParser.add_option(opt_str[, ...], attr=value, ...)`788789Для определения опции только с короткой строкой опции:790791```python792parser.add_option("-f", attr=value, ...)793```794795А для определения опции только с длинной строкой опции:796797```python798parser.add_option("--foo", attr=value, ...)799```800801Именованные аргументы определяют атрибуты нового объекта Option. Наиболее важный атрибут опции – [`action`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.action), и он в значительной степени определяет, какие другие атрибуты имеют значение или обязательны. Если передать нерелевантные атрибуты опции или не передать обязательные, `optparse` вызывает исключение `OptionError` с объяснением ошибки.802803Атрибут *action* опции определяет, что `optparse` делает при встрече этой опции в командной строке. Стандартные действия опций, жёстко закодированные в `optparse`:804805**`"store"`**806807сохранить аргумент опции (по умолчанию)808809**`"store_const"`**810811сохранить константное значение812813**`"store_true"`**814815сохраняет истинное значение816817**`"store_false"`**818819сохраняет ложное значение820821**`"append"`**822823добавить аргумент этой опции в список824825**`"append_const"`**826827добавить константное значение в список828829**`"count"`**830831увеличить счётчик на единицу832833**`\"колбэк\"`**834835вызвать указанную функцию836837**`"help"`**838839вывести сообщение об использовании, включающее все опции и документацию к ним840841(Если не указать действие, по умолчанию используется `"store"`. Для этого действия можно также указать атрибуты опции [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type) и [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest); см. [*Standard option actions*](https://python-all.ru/3.1/library/optparse.html#optparse-standard-option-actions).)842843Как видите, большинство действий сводятся к сохранению или обновлению значения где-либо. `optparse` всегда создаёт для этого специальный объект, традиционно называемый `options` (на самом деле это экземпляр `optparse.Values`). Аргументы опций (и различные другие значения) хранятся как атрибуты этого объекта в соответствии с атрибутом опции [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) (назначение).844845Например, при вызове846847```python848parser.parse_args()849```850851одно из первых действий `optparse` – создать объект `options`:852853```python854options = Values()855```856857Если одна из опций в этом анализаторе определена с помощью858859```python860parser.add_option("-f", "--file", action="store", type="string", dest="filename")861```862863и разбираемая командная строка включает любую из следующих:864865```python866-ffoo867-f foo868--file=foo869--file foo870```871872затем `optparse`, увидев эту опцию, выполнит эквивалент873874```python875options.filename = "foo"876```877878Атрибуты опции [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type) и [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) почти так же важны, как [`action`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.action), но [`action`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.action) – единственный, который имеет смысл для *всех* опций.879880### 15.4.3.4. Атрибуты опций881882Следующие атрибуты опций могут быть переданы в качестве именованных аргументов в [`OptionParser.add_option()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.add_option). Если передать атрибут, не относящийся к данной опции, или не передать обязательный атрибут, `optparse` возбуждает `OptionError`.883884#### `Option.action`885886(по умолчанию: `"store"`)887888Определяет поведение `optparse` при обнаружении этой опции в командной строке; доступные варианты описаны [*здесь*](https://python-all.ru/3.1/library/optparse.html#optparse-standard-option-actions).889890#### `Option.type`891892(по умолчанию: `"string"`)893894Тип аргумента, ожидаемый этой опцией (например, `"string"` или `"int"`); доступные типы опций описаны [*здесь*](https://python-all.ru/3.1/library/optparse.html#optparse-standard-option-types).895896#### `Option.dest`897898(по умолчанию: выводится из строк опций)899900Если действие опции подразумевает запись или изменение значения где-либо, это указывает `optparse`, куда его записывать: [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) задаёт атрибут объекта `options`, который `optparse` создаёт при разборе командной строки.901902#### `Option.default`903904Значение, которое следует использовать для назначения этой опции, если опция не обнаружена в командной строке. См. также905906[`OptionParser.set_defaults()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.set_defaults)907908.909910#### `Option.nargs`911912(по умолчанию: 1)913914Сколько аргументов типа [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type) должно быть обработано при обнаружении этой опции. Если \> 1, `optparse` сохранит кортеж значений в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest).915916#### `Option.const`917918Для действий, сохраняющих постоянное значение, – само это постоянное значение.919920#### `Option.choices`921922Для опций типа923924`"choice"`925926– список строк, из которых пользователь может выбирать.927928#### `Option.callback`929930Для опций с действием931932`"колбэк"`933934– вызываемый объект, который будет вызван при обнаружении этой опции. См. раздел935936[*Option Callbacks*](https://python-all.ru/3.1/library/optparse.html#optparse-option-callbacks)937938для получения подробностей об аргументах, передаваемых вызываемому объекту.939940#### `Option.callback_args`941942#### `Option.callback_kwargs`943944Дополнительные позиционные и именованные аргументы для передачи в945946`колбэк`947948после четырёх стандартных аргументов колбэка.949950#### `Option.help`951952Текст справки для этой опции, выводимый при перечислении всех доступных опций после того, как пользователь укажет опцию953954[`help`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.help)955956(например,957958`--help`959960). Если текст справки не указан, опция будет перечислена без текста справки. Чтобы скрыть эту опцию, используйте специальное значение961962`optparse.SUPPRESS_HELP`963964.965966#### `Option.metavar`967968(по умолчанию: выводится из строк опций)969970Stand-in for the option argument(s) to use when printing help text. See section [*Tutorial*](https://python-all.ru/3.1/library/optparse.html#optparse-tutorial) for an example.971972### 15.4.3.5. Стандартные действия опций973974Различные действия опций имеют несколько разные требования и эффекты. Большинство действий имеют несколько соответствующих атрибутов, которые можно указать, чтобы направить поведение `optparse`; некоторые имеют обязательные атрибуты, которые необходимо указать для любой опции, использующей это действие.975976- `"store"` \[соответствующие: [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type), [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest), [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs), [`choices`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.choices)\]977978 За опцией должен следовать аргумент, который преобразуется в значение согласно [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type) и сохраняется в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest). Если [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs) \> 1, из командной строки будет потреблено несколько аргументов; все они будут преобразованы согласно [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type) и сохранены в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) как кортеж. См. раздел [*Стандартные типы опций*](https://python-all.ru/3.1/library/optparse.html#optparse-standard-option-types).979980 Если указан [`choices`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.choices) (список или кортеж строк), по умолчанию тип принимает значение `"choice"`.981982 Если [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type) не указан, по умолчанию он принимает значение `"string"`.983984 Если [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) не указан, `optparse` выводит назначение из первой длинной строки опции (например, `--foo-bar` подразумевает `foo_bar`). Если длинных строк опций нет, `optparse` выводит назначение из первой короткой строки опции (например, `-f` подразумевает `f`).985986 Пример:987988 ```python989 parser.add_option("-f")990 parser.add_option("-p", type="float", nargs=3, dest="point")991 ```992993 В процессе разбора командной строки994995 ```python996 -f foo.txt -p 1 -3.5 4 -fbar.txt997 ```998999 `optparse` установит10001001 ```python1002 options.f = "foo.txt"1003 options.point = (1.0, -3.5, 4.0)1004 options.f = "bar.txt"1005 ```1006- `"store_const"` \[обязательно: [`const`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.const); относящиеся: [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest)\]10071008 Значение [`const`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.const) сохраняется в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest).10091010 Пример:10111012 ```python1013 parser.add_option("-q", "--quiet",1014 action="store_const", const=0, dest="verbose")1015 parser.add_option("-v", "--verbose",1016 action="store_const", const=1, dest="verbose")1017 parser.add_option("--noisy",1018 action="store_const", const=2, dest="verbose")1019 ```10201021 Если обнаружено `--noisy`, `optparse` установит10221023 ```python1024 options.verbose = 21025 ```1026- `"store_true"` \[относящиеся: [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest)\]10271028 Частный случай `"store_const"`, который сохраняет истинное значение в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest).1029- `"store_false"` \[относящиеся: [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest)\]10301031 Как `"store_true"`, но сохраняет ложное значение.10321033 Пример:10341035 ```python1036 parser.add_option("--clobber", action="store_true", dest="clobber")1037 parser.add_option("--no-clobber", action="store_false", dest="clobber")1038 ```1039- `"append"` \[относящиеся: [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type), [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest), [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs), [`choices`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.choices)\]10401041 За опцией должен следовать аргумент, который добавляется в список в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest). Если значение по умолчанию для [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) не задано, пустой список автоматически создаётся при первом обнаружении этой опции в командной строке `optparse`. Если [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs) \> 1, потребляется несколько аргументов, и кортеж длиной [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs) добавляется к [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest).10421043 Значения по умолчанию для [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type) и [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) такие же, как для действия `"store"`.10441045 Пример:10461047 ```python1048 parser.add_option("-t", "--tracks", action="append", type="int")1049 ```10501051 Если в командной строке обнаружено `-t3`, `optparse` выполняет эквивалент:10521053 ```python1054 options.tracks = []1055 options.tracks.append(int("3"))1056 ```10571058 Если чуть позже встречается `--tracks=4`, он делает:10591060 ```python1061 options.tracks.append(int("4"))1062 ```1063- `"append_const"` \[обязательно: [`const`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.const); относящиеся: [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest)\]10641065 Как `"store_const"`, но значение [`const`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.const) добавляется в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest); как и в случае `"append"`, [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) по умолчанию равен `None`, и пустой список автоматически создаётся при первой встрече опции.1066- `"count"` \[относящиеся: [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest)\]10671068 Увеличивает целое число, хранящееся в [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest). Если значение по умолчанию не указано, [`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest) устанавливается в ноль перед первым увеличением.10691070 Пример:10711072 ```python1073 parser.add_option("-v", action="count", dest="verbosity")1074 ```10751076 Когда `-v` встречается в командной строке в первый раз, `optparse` выполняет эквивалент:10771078 ```python1079 options.verbosity = 01080 options.verbosity += 11081 ```10821083 Каждое последующее появление `-v` приводит к10841085 ```python1086 options.verbosity += 11087 ```1088- `"колбэк"` \[обязательно: [`колбэк`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback); относящиеся: [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type), [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs), [`callback_args`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_args), [`callback_kwargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_kwargs)\]10891090 Вызывает функцию, указанную колбэком [`колбэк`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback), которая вызывается как10911092 ```python1093 func(option, opt_str, value, parser, *args, **kwargs)1094 ```10951096 Смотрите раздел [*Колбэки опций*](https://python-all.ru/3.1/library/optparse.html#optparse-option-callbacks) для подробностей.1097- `"help"`10981099 Выводит полное справочное сообщение для всех опций текущего анализатора опций. Справочное сообщение строится из строки `usage`, переданной конструктору OptionParser, и строки [`help`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.help), переданной каждой опции.11001101 Если для опции не указана строка [`help`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.help), она всё равно будет включена в справочное сообщение. Чтобы полностью исключить опцию, используйте специальное значение `optparse.SUPPRESS_HELP`.11021103 `optparse` автоматически добавляет опцию [`help`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.help) во все OptionParsers, поэтому обычно не нужно создавать её отдельно.11041105 Пример:11061107 ```python1108 from optparse import OptionParser, SUPPRESS_HELP11091110 # обычно опция справки добавляется автоматически, но её можно1111 # подавить, используя аргумент add_help_option1112 parser = OptionParser(add_help_option=False)11131114 parser.add_option("-h", "--help", action="help")1115 parser.add_option("-v", action="store_true", dest="verbose",1116 help="Be moderately verbose")1117 parser.add_option("--file", dest="filename",1118 help="Input file to read data from")1119 parser.add_option("--secret", help=SUPPRESS_HELP)1120 ```11211122 Если `optparse` обнаруживает в командной строке `-h` или `--help`, он выводит в stdout что-то вроде следующего сообщения справки (при условии, что `sys.argv[0]` равно `"foo.py"`):11231124 ```text1125 Usage: foo.py [options]11261127 Options:1128 -h, --help Show this help message and exit1129 -v Be moderately verbose1130 --file=FILENAME Input file to read data from1131 ```11321133 После вывода сообщения справки `optparse` завершает процесс с помощью `sys.exit(0)`.1134- `"version"`11351136 Выводит номер версии, переданный OptionParser, в stdout и завершает работу. Номер версии фактически форматируется и выводится методом `print_version()` класса OptionParser. Обычно это актуально, только если аргумент `version` передан конструктору OptionParser. Как и в случае с опциями [`help`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.help), редко приходится создавать опции `version`, поскольку `optparse` автоматически добавляет их при необходимости.11371138### 15.4.3.6. Стандартные типы опций11391140`optparse` имеет пять встроенных типов опций: `"string"`, `"int"`, `"choice"`, `"float"` и `"complex"`. Если нужно добавить новые типы опций, смотрите раздел [*Расширение optparse*](https://python-all.ru/3.1/library/optparse.html#optparse-extending-optparse).11411142Аргументы строковых опций никак не проверяются и не преобразуются: текст из командной строки сохраняется в целевом атрибуте (или передаётся колбэку) как есть.11431144Целочисленные аргументы (тип `"int"`) разбираются следующим образом:11451146- если число начинается с `0x`, оно разбирается как шестнадцатеричное число1147- если число начинается с `0`, оно разбирается как восьмеричное1148- если число начинается с `0b`, оно разбирается как двоичное число1149- в противном случае число разбирается как десятичное11501151Преобразование выполняется вызовом [`int()`](https://python-all.ru/3.1/library/functions.html#int) с соответствующим основанием (2, 8, 10 или 16). Если это не удаётся, то `optparse` тоже завершится ошибкой, хотя и с более полезным сообщением.11521153Аргументы опций `"float"` и `"complex"` преобразуются напрямую с помощью [`float()`](https://python-all.ru/3.1/library/functions.html#float) и [`complex()`](https://python-all.ru/3.1/library/functions.html#complex), с аналогичной обработкой ошибок.11541155Опции `"choice"` являются подтипом опций `"string"`. Атрибут [`choices`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.choices) опции (последовательность строк) определяет множество допустимых аргументов опции. `optparse.check_choice()` сравнивает предоставленные пользователем аргументы с этим основным списком и возбуждает `OptionValueError`, если указана недопустимая строка.11561157### 15.4.3.7. Разбор аргументов11581159Весь смысл создания и настройки OptionParser – вызвать его метод `parse_args()`:11601161```python1162(options, args) = parser.parse_args(args=None, values=None)1163```11641165где входные параметры:11661167**`args`**11681169список аргументов для обработки (по умолчанию:11701171`sys.argv[1:]`11721173)11741175**`values`**11761177объект11781179`optparse.Values`11801181для сохранения аргументов параметров (по умолчанию: новый экземпляр11821183`Values`11841185) – если передать существующий объект, значения параметров по умолчанию не будут в нём инициализированы11861187а возвращаемые значения –11881189**`options`**11901191тот же объект, который был передан как11921193`values`11941195, или экземпляр optparse.Values, созданный11961197`optparse`11981199**`args`**12001201оставшиеся позиционные аргументы после обработки всех опций12021203Наиболее распространённый вариант использования – не указывать ни один из именованных аргументов. Если передать `values`, он будет изменяться повторными вызовами [`setattr()`](https://python-all.ru/3.1/library/functions.html#setattr) (примерно по одному на каждый аргумент опции, сохраняемый в её назначении) и возвращён методом `parse_args()`.12041205Если `parse_args()` встречает какие-либо ошибки в списке аргументов, он вызывает метод `error()` класса OptionParser с соответствующим сообщением об ошибке для конечного пользователя. Это в конечном итоге приводит к завершению процесса с кодом выхода 2 (традиционный код выхода Unix для ошибок командной строки).12061207### 15.4.3.8. Запросы и управление анализатором опций12081209Поведение парсера опций по умолчанию можно слегка настроить, а также можно заглянуть внутрь парсера и посмотреть, что там есть. OptionParser предоставляет несколько методов, которые в этом помогут:12101211#### `OptionParser.disable_interspersed_args()`12121213Устанавливает, что разбор останавливается на первой не-опции. Например, если `-a` и `-b` – это простые опции без аргументов, `optparse` обычно принимает такой синтаксис:12141215```python1216prog -a arg1 -b arg21217```12181219и обрабатывает его как эквивалент12201221```python1222prog -a -b arg1 arg21223```12241225Чтобы отключить эту возможность, вызовите [`disable_interspersed_args()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.disable_interspersed_args). Это восстанавливает традиционный синтаксис Unix, при котором разбор опций останавливается на первом не-опционном аргументе.12261227Используйте это, если у вас есть обработчик команд, который запускает другую команду с собственными опциями, и нужно гарантировать, что эти опции не будут перепутаны. Например, каждая команда может иметь свой набор опций.12281229#### `OptionParser.enable_interspersed_args()`12301231Настраивает разбор на то, чтобы не останавливаться на первом не-опции, позволяя перемешивать ключи с аргументами команды. Это поведение по умолчанию.12321233#### `OptionParser.get_option(opt_str)`12341235Возвращает экземпляр Option с опционной строкой12361237*opt\_str*12381239или12401241`None`12421243, если ни одна опция не имеет такой строки.12441245#### `OptionParser.has_option(opt_str)`12461247Возвращает true, если OptionParser содержит опцию с опционной строкой12481249*opt\_str*12501251(например,12521253`-q`12541255или12561257`--verbose`12581259).12601261#### `OptionParser.remove_option(opt_str)`12621263If the12641265[`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser)12661267has an option corresponding to12681269*opt\_str*12701271, that option is removed. If that option provided any other option strings, all of those option strings become invalid. If12721273*opt\_str*12741275does not occur in any option belonging to this12761277[`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser)12781279, raises12801281[`ValueError`](https://python-all.ru/3.1/library/exceptions.html#ValueError)12821283.12841285### 15.4.3.9. Конфликты между опциями12861287Если быть невнимательным, легко определить опции с конфликтующими строками опций:12881289```python1290parser.add_option("-n", "--dry-run", ...)1291[...]1292parser.add_option("-n", "--noisy", ...)1293```12941295(Это особенно актуально, если определён собственный подкласс OptionParser с некоторыми стандартными опциями.)12961297Каждый раз при добавлении опции `optparse` проверяет конфликты с существующими опциями. Если они находятся, вызывается текущий механизм разрешения конфликтов. Можно задать механизм разрешения конфликтов либо в конструкторе:12981299```python1300parser = OptionParser(..., conflict_handler=handler)1301```13021303или отдельным вызовом:13041305```python1306parser.set_conflict_handler(handler)1307```13081309Доступные обработчики конфликтов:13101311> **`"error"` (по умолчанию)**1312>1313> считать конфликты опций программной ошибкой и возбуждать1314>1315> `OptionConflictError`1316>1317> **`\"resolve\"`**1318>1319> разрешать конфликты опций интеллектуально (см. ниже)13201321В качестве примера определим [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser), который разрешает конфликты интеллектуально, и добавим к нему конфликтующие параметры:13221323```python1324parser = OptionParser(conflict_handler="resolve")1325parser.add_option("-n", "--dry-run", ..., help="do no harm")1326parser.add_option("-n", "--noisy", ..., help="be noisy")1327```13281329На этом этапе `optparse` обнаруживает, что ранее добавленная опция уже использует строку опции `-n`. Поскольку `conflict_handler` равен `"resolve"`, он разрешает ситуацию, удаляя `-n` из списка строк опции более ранней опции. Теперь `--dry-run` – единственный способ для пользователя активировать эту опцию. Если пользователь запросит справку, сообщение справки отразит это:13301331```python1332Options:1333 --dry-run do no harm1334 [...]1335 -n, --noisy be noisy1336```13371338Можно сокращать строки опций для ранее добавленной опции, пока их не останется, и у пользователя не будет возможности вызвать эту опцию из командной строки. В этом случае `optparse` полностью удаляет эту опцию, так что она не появляется в тексте справки или где-либо ещё. Продолжая с нашим существующим OptionParser:13391340```python1341parser.add_option("--dry-run", ..., help="new dry-run option")1342```13431344На этом этапе исходная опция `-n`/`--dry-run` больше не доступна, поэтому `optparse` удаляет её, оставляя такой текст справки:13451346```python1347Options:1348 [...]1349 -n, --noisy be noisy1350 --dry-run new dry-run option1351```13521353### 15.4.3.10. Очистка13541355Экземпляры OptionParser имеют несколько циклических ссылок. Это не должно быть проблемой для сборщика мусора Python, но вы можете захотеть разорвать циклические ссылки явно, вызвав `destroy()` для вашего OptionParser после завершения работы с ним. Это особенно полезно в долго работающих приложениях, где большие графы объектов достижимы из вашего OptionParser.13561357### 15.4.3.11. Другие методы13581359OptionParser поддерживает несколько других открытых методов:13601361#### `OptionParser.set_usage(usage)`13621363Устанавливает строку использования в соответствии с правилами, описанными выше для13641365`usage`13661367аргумента-ключевого слова конструктора. Передача13681369`None`13701371устанавливает строку использования по умолчанию; используйте13721373`optparse.SUPPRESS_USAGE`13741375для подавления сообщения об использовании.13761377#### `OptionParser.print_usage(file=None)`13781379Выводит сообщение об использовании для текущей программы (13801381`self.usage`13821383) в13841385*file*13861387(по умолчанию stdout). Любое вхождение строки13881389`%prog`13901391в13921393`self.usage`13941395заменяется на имя текущей программы. Ничего не делает, если13961397`self.usage`13981399пуст или не определён.14001401#### `OptionParser.get_usage()`14021403То же, что и14041405[`print_usage()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.print_usage)14061407, но возвращает строку использования вместо её вывода.14081409#### `OptionParser.set_defaults(dest=value, ...)`14101411Устанавливает значения по умолчанию для нескольких назначений параметров одновременно. Использование [`set_defaults()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.set_defaults) – предпочтительный способ установки значений по умолчанию для параметров, поскольку несколько параметров могут совместно использовать одно назначение. Например, если несколько параметров «режим» устанавливают одно и то же назначение, любой из них может установить значение по умолчанию, и последний выигрывает:14121413```python1414parser.add_option("--advanced", action="store_const",1415 dest="mode", const="advanced",1416 default="novice") # переопределено ниже1417parser.add_option("--novice", action="store_const",1418 dest="mode", const="novice",1419 default="advanced") # переопределяет вышеуказанную настройку1420```14211422Чтобы избежать этой путаницы, используйте [`set_defaults()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.set_defaults):14231424```python1425parser.set_defaults(mode="advanced")1426parser.add_option("--advanced", action="store_const",1427 dest="mode", const="advanced")1428parser.add_option("--novice", action="store_const",1429 dest="mode", const="novice")1430```14311432## 15.4.4. Опциональные колбэки14331434Когда встроенных действий и типов `optparse` недостаточно для ваших нужд, у вас есть два варианта: расширить `optparse` или определить опцию с колбэком. Расширение `optparse` более универсально, но избыточно для многих простых случаев. Часто достаточно простого колбэка.14351436Определение опции-колбэка состоит из двух шагов:14371438- определите саму опцию, используя действие `"колбэк"`1439- написать колбэк – функцию (или метод), которая принимает как минимум четыре аргумента, как описано ниже14401441### 15.4.4.1. Определение опции с колбэком14421443Как всегда, самый простой способ определить опцию с колбэком – использовать метод [`OptionParser.add_option()`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser.add_option). Кроме [`action`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.action), единственным атрибутом опции, который необходимо указать, является `колбэк` – функция, которую нужно вызвать:14441445```python1446parser.add_option("-c", action="callback", callback=my_callback)1447```14481449`колбэк` – это функция (или другой вызываемый объект), поэтому вы должны уже определить `my_callback()` до создания этой опции с колбэком. В этом простом случае `optparse` даже не знает, принимает ли `-c` какие-то аргументы, что обычно означает, что опция не принимает аргументов – достаточно лишь присутствия `-c` в командной строке. Однако в некоторых обстоятельствах колбэк может потреблять произвольное число аргументов командной строки. Вот здесь написание колбэков становится сложным; это рассматривается далее в этом разделе.14501451`optparse` всегда передаёт вашему колбэку четыре определённых аргумента, и он передаст дополнительные аргументы только если вы укажете их через [`callback_args`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_args) и [`callback_kwargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_kwargs). Таким образом, минимальная сигнатура функции колбэка:14521453```python1454def my_callback(option, opt, value, parser):1455```14561457Четыре аргумента колбэка описаны ниже.14581459Есть ещё несколько атрибутов опции, которые можно указать при определении опции-колбэка:14601461**[`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type)**14621463имеет своё обычное значение: как и в случае действий14641465`"store"`14661467или14681469`"append"`14701471, он предписывает14721473`optparse`14741475потребить один аргумент и преобразовать его в14761477[`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type)14781479. Однако вместо сохранения преобразованного значения,14801481`optparse`14821483передаёт его в функцию обратного вызова.14841485**[`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs)**14861487также имеет своё обычное значение: если он указан и больше 1,14881489`optparse`14901491потребит14921493[`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs)14941495аргументов, каждый из которых должен быть преобразуем в14961497[`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type)14981499. Затем он передаёт кортеж преобразованных значений в функцию обратного вызова.15001501**[`callback_args`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_args)**15021503кортеж дополнительных позиционных аргументов, передаваемых колбэку15041505**[`callback_kwargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_kwargs)**15061507словарь дополнительных именованных аргументов, передаваемых колбэку15081509### 15.4.4.2. Как вызываются колбэки15101511Все колбэки вызываются следующим образом:15121513```python1514func(option, opt_str, value, parser, *args, **kwargs)1515```15161517где15181519**`option`**15201521это экземпляр Option, который вызывает колбэк15221523**`opt_str`**15241525– это строка параметра, видимая в командной строке, которая запускает колбэк. (Если была использована сокращённая длинная опция,15261527`opt_str`15281529будет полной, канонической строкой параметра – например, если пользователь поместил15301531`--foo`15321533в командную строку как сокращение для15341535`--foobar`15361537, то15381539`opt_str`15401541будет15421543`"--foobar"`15441545.)15461547**`value`**15481549это аргумент данной опции, указанный в командной строке.15501551`optparse`15521553ожидает аргумент только если установлен15541555[`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type)15561557; тип15581559`value`15601561будет соответствовать типу, подразумеваемому типом опции. Если15621563[`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type)15641565для этой опции равен15661567`None`15681569(аргумент не ожидается), то15701571`value`15721573будет15741575`None`15761577. Если15781579[`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs)15801581\> 1,15821583`value`15841585будет кортежем значений подходящего типа.15861587**`parser`**15881589это экземпляр OptionParser, управляющий всем процессом; он полезен тем, что через его атрибуты можно получить доступ к некоторым другим интересным данным:15901591**`parser.largs`**15921593текущий список оставшихся аргументов, т.е. аргументов, которые были потреблены, но не являются ни опциями, ни аргументами опций. Можно свободно изменять15941595`parser.largs`15961597, например, добавляя в него дополнительные аргументы. (Этот список станет15981599`args`16001601, вторым возвращаемым значением16021603`parse_args()`16041605.)16061607**`parser.rargs`**16081609текущий список оставшихся аргументов, т.е. с удалёнными16101611`opt_str`16121613и16141615`value`16161617(если применимо), и только следующие за ними аргументы всё ещё присутствуют. Можно свободно изменять16181619`parser.rargs`16201621, например, потребляя больше аргументов.16221623**`parser.values`**16241625объект, в котором по умолчанию хранятся значения опций (экземпляр optparse.OptionValues). Это позволяет колбэкам использовать тот же механизм, что и остальная часть16261627`optparse`16281629, для хранения значений опций; не нужно возиться с глобальными переменными или замыканиями. Также можно получить доступ или изменить значения любых опций, уже встреченных в командной строке.16301631**`args`**16321633представляет собой кортеж произвольных позиционных аргументов, предоставленных через атрибут опции16341635[`callback_args`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_args)16361637.16381639**`kwargs`**16401641представляет собой словарь произвольных именованных аргументов, предоставленных через16421643[`callback_kwargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.callback_kwargs)16441645.16461647### 15.4.4.3. Возбуждение ошибок в колбэке16481649Функция обратного вызова должна возбуждать `OptionValueError`, если возникли проблемы с опцией или её аргументом(ами). `optparse` перехватывает это и завершает программу, выводя в stderr указанное сообщение об ошибке. Сообщение должно быть ясным, кратким, точным и указывать на виновную опцию. В противном случае пользователю будет трудно понять, что было сделано не так.16501651### 15.4.4.4. Пример колбэка 1: простейший колбэк16521653Вот пример опции-колбэка, которая не принимает аргументов и просто записывает факт своего появления:16541655```python1656def record_foo_seen(option, opt_str, value, parser):1657 parser.values.saw_foo = True16581659parser.add_option("--foo", action="callback", callback=record_foo_seen)1660```16611662Конечно, вы можете сделать это с помощью действия `"store_true"`.16631664### 15.4.4.5. Пример колбэка 2: проверка порядка опций16651666Вот чуть более интересный пример: записать факт, что `-a` встречен, но аварийно завершиться, если он появляется после `-b` в командной строке.16671668```python1669def check_order(option, opt_str, value, parser):1670 if parser.values.b:1671 raise OptionValueError("can't use -a after -b")1672 parser.values.a = 11673[...]1674parser.add_option("-a", action="callback", callback=check_order)1675parser.add_option("-b", action="store_true", dest="b")1676```16771678### 15.4.4.6. Пример колбэка 3: проверка порядка опций (обобщённый вариант)16791680Если вы хотите повторно использовать этот колбэк для нескольких похожих опций (установить флаг, но аварийно завершиться, если `-b` уже был встречен), потребуется немного доработки: сообщение об ошибке и устанавливаемый флаг должны быть обобщены.16811682```python1683def check_order(option, opt_str, value, parser):1684 if parser.values.b:1685 raise OptionValueError("can't use %s after -b" % opt_str)1686 setattr(parser.values, option.dest, 1)1687[...]1688parser.add_option("-a", action="callback", callback=check_order, dest='a')1689parser.add_option("-b", action="store_true", dest="b")1690parser.add_option("-c", action="callback", callback=check_order, dest='c')1691```16921693### 15.4.4.7. Пример колбэка 4: проверка произвольного условия16941695Конечно, можно задать любое условие – вы не ограничены проверкой значений уже определённых параметров. Например, если есть параметры, которые не должны вызываться в полнолуние, достаточно сделать так:16961697```python1698def check_moon(option, opt_str, value, parser):1699 if is_moon_full():1700 raise OptionValueError("%s option invalid when moon is full"1701 % opt_str)1702 setattr(parser.values, option.dest, 1)1703[...]1704parser.add_option("--foo",1705 action="callback", callback=check_moon, dest="foo")1706```17071708(Определение `is_moon_full()` оставляется читателю в качестве упражнения.)17091710### 15.4.4.8. Пример колбэка 5: фиксированные аргументы17111712Ситуация становится чуть более интересной, когда вы определяете опции с обратным вызовом, принимающие фиксированное количество аргументов. Указание, что опция с колбэком принимает аргументы, аналогично определению опции `"store"` или `"append"`: если вы определяете [`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type), то опция принимает один аргумент, который должен быть преобразуем к этому типу; если вы дополнительно определяете [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs), то опция принимает [`nargs`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.nargs) аргументов.17131714Вот пример, который просто эмулирует стандартное действие `"store"`:17151716```python1717def store_value(option, opt_str, value, parser):1718 setattr(parser.values, option.dest, value)1719[...]1720parser.add_option("--foo",1721 action="callback", callback=store_value,1722 type="int", nargs=3, dest="foo")1723```17241725Обратите внимание, что `optparse` самостоятельно заботится о потреблении 3 аргументов и преобразовании их в целые числа; всё, что нужно сделать – сохранить их. (Или что-то ещё; очевидно, для этого примера колбэк не нужен.)17261727### 15.4.4.9. Пример колбэка 6: переменное число аргументов17281729Дело усложняется, когда требуется, чтобы опция принимала переменное число аргументов. В этом случае необходимо написать колбэк, поскольку `optparse` не предоставляет для этого встроенных возможностей. И придётся разобраться с некоторыми тонкостями традиционного разбора командной строки Unix, которые `optparse` обычно обрабатывает автоматически. В частности, колбэки должны реализовывать стандартные правила для аргументов `--` и `-`:17301731- как `--`, так и `-` могут быть аргументами параметра1732- голый `--` (если не является аргументом какого-либо параметра): остановить обработку командной строки и отбросить `--`1733- голый `-` (если не является аргументом какой-либо опции): остановить обработку командной строки, но сохранить `-` (добавить его в `parser.largs`)17341735Если требуется опция, принимающая переменное число аргументов, нужно учитывать несколько тонких и коварных моментов. Конкретная реализация будет зависеть от того, на какие компромиссы вы готовы пойти ради своего приложения (именно поэтому `optparse` не поддерживает такие вещи напрямую).17361737Тем не менее, вот пример попытки создать колбэк для параметра с переменным числом аргументов:17381739```python1740 def vararg_callback(option, opt_str, value, parser):1741 assert value is None1742 value = []17431744 def floatable(str):1745 try:1746 float(str)1747 return True1748 except ValueError:1749 return False17501751 for arg in parser.rargs:1752 # останавливаться на опциях вида --foo1753 if arg[:2] == "--" and len(arg) > 2:1754 break1755 # останавливаться на -a, но не на -3 или -3.01756 if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):1757 break1758 value.append(arg)17591760 del parser.rargs[:len(value)]1761 setattr(parser.values, option.dest, value)17621763[...]1764parser.add_option("-c", "--callback", dest="vararg_attr",1765 action="callback", callback=vararg_callback)1766```17671768## 15.4.5. Расширение `optparse`17691770Поскольку двумя основными управляющими факторами, определяющими, как `optparse` интерпретирует опции командной строки, являются действие и тип каждой опции, наиболее вероятное направление расширения – добавление новых действий и новых типов.17711772### 15.4.5.1. Добавление новых типов17731774Чтобы добавить новые типы, нужно определить собственный подкласс класса `optparse` `Option`. Этот класс имеет несколько атрибутов, определяющих типы `optparse`: [`TYPES`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.TYPES) и [`TYPE_CHECKER`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.TYPE_CHECKER).17751776#### `Option.TYPES`17771778Кортеж имен типов; в вашем подклассе просто определите новый кортеж17791780[`TYPES`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.TYPES)17811782, который расширяет стандартный.17831784#### `Option.TYPE_CHECKER`17851786Словарь, отображающий имена типов в функции проверки типа. Функция проверки типа имеет следующую сигнатуру:17871788```python1789def check_mytype(option, opt, value)1790```17911792где `option` – это экземпляр `Option`, `opt` – строка опции (например, `-f`), а `value` – строка из командной строки, которая должна быть проверена и преобразована в нужный тип. `check_mytype()` должна вернуть объект гипотетического типа `mytype`. Значение, возвращаемое функцией проверки типа, в конечном итоге окажется в экземпляре OptionValues, возвращаемом `OptionParser.parse_args()`, или будет передано колбэку как параметр `value`.17931794Ваша функция проверки типа должна вызывать `OptionValueError`, если она сталкивается с какими-либо проблемами. `OptionValueError` принимает один строковый аргумент, который передаётся как есть методу [`OptionParser`](https://python-all.ru/3.1/library/optparse.html#optparse.OptionParser)‘s `error()`, который, в свою очередь, добавляет имя программы и строку `"error:"` и выводит всё в stderr перед завершением процесса.17951796Вот глупый пример, демонстрирующий добавление типа опции `"complex"` для разбора комплексных чисел в стиле Python из командной строки. (Теперь это ещё глупее, чем раньше, потому что в `optparse` 1.3 уже есть встроенная поддержка комплексных чисел, но неважно.)17971798Сначала необходимые импорты:17991800```python1801from copy import copy1802from optparse import Option, OptionValueError1803```18041805Сначала нужно определить вашу функцию проверки типа, так как на неё ссылаются позже (в атрибуте класса [`TYPE_CHECKER`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.TYPE_CHECKER) вашего подкласса Option):18061807```python1808def check_complex(option, opt, value):1809 try:1810 return complex(value)1811 except ValueError:1812 raise OptionValueError(1813 "option %s: invalid complex value: %r" % (opt, value))1814```18151816Наконец, подкласс Option:18171818```python1819class MyOption (Option):1820 TYPES = Option.TYPES + ("complex",)1821 TYPE_CHECKER = copy(Option.TYPE_CHECKER)1822 TYPE_CHECKER["complex"] = check_complex1823```18241825(Если бы мы не сделали `copy()` от [`Option.TYPE_CHECKER`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.TYPE_CHECKER), то в итоге изменили бы атрибут [`TYPE_CHECKER`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.TYPE_CHECKER) класса `optparse` Option. В Python нет ничего, что помешало бы это сделать, кроме хороших манер и здравого смысла.)18261827Вот и всё! Теперь можно написать скрипт, использующий новый тип опций так же, как и любой другой скрипт на основе `optparse`, за исключением того, что нужно указать OptionParser использовать MyOption вместо Option:18281829```python1830parser = OptionParser(option_class=MyOption)1831parser.add_option("-c", type="complex")1832```18331834В качестве альтернативы можно составить собственный список опций и передать его OptionParser; если не использовать `add_option()` указанным выше способом, не нужно сообщать OptionParser, какой класс опций использовать:18351836```python1837option_list = [MyOption("-c", action="store", type="complex", dest="c")]1838parser = OptionParser(option_list=option_list)1839```18401841### 15.4.5.2. Добавление новых действий18421843Добавление новых действий немного сложнее, потому что нужно понимать, что у `optparse` есть несколько классификаций действий:18441845**«store»-действия**18461847действия, в результате которых18481849`optparse`18501851сохраняет значение в атрибуте текущего экземпляра OptionValues; для таких опций требуется указать атрибут18521853[`dest`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.dest)18541855в конструкторе Option.18561857**«typed»-действия**18581859действия, которые берут значение из командной строки и ожидают, что оно будет определённого типа; точнее, строка, которую можно преобразовать в определённый тип. Такие опции требуют атрибута18601861[`type`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.type)18621863в конструкторе Option.18641865Это пересекающиеся множества: некоторые действия «store» по умолчанию – `"store"`, `"store_const"`, `"append"` и `"count"`, в то время как действия «typed» по умолчанию – `"store"`, `"append"` и `"колбэк"`.18661867При добавлении действия его нужно отнести к категории, включив как минимум в один из следующих атрибутов класса Option (все они являются списками строк):18681869#### `Option.ACTIONS`18701871Все действия должны быть перечислены в ACTIONS.18721873#### `Option.STORE_ACTIONS`18741875«store»-действия дополнительно перечисляются здесь.18761877#### `Option.TYPED_ACTIONS`18781879«typed»-действия дополнительно перечисляются здесь.18801881#### `Option.ALWAYS_TYPED_ACTIONS`18821883Действия, которые всегда требуют тип (т.е. опции которых всегда принимают значение), дополнительно перечислены здесь. Единственный эффект этого заключается в том, что18841885`optparse`18861887назначает тип по умолчанию,18881889`"string"`18901891, опциям без явного типа, чьё действие перечислено в18921893[`ALWAYS_TYPED_ACTIONS`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.ALWAYS_TYPED_ACTIONS)18941895.18961897Чтобы реализовать новое действие, необходимо переопределить метод Option `take_action()` и добавить ветвь, распознающую это действие.18981899Например, добавим действие `"extend"`. Оно похоже на стандартное действие `"append"`, но вместо того, чтобы брать одно значение из командной строки и добавлять его в конец существующего списка, `"extend"` принимает несколько значений в одной строке с разделителями-запятыми и расширяет существующий список этими значениями. То есть, если `--names` – опция `"extend"` типа `"string"`, то командная строка19001901```python1902--names=foo,bar --names blah --names ding,dong1903```19041905приведёт к списку19061907```python1908["foo", "bar", "blah", "ding", "dong"]1909```19101911Снова определим подкласс Option:19121913```python1914class MyOption(Option):19151916 ACTIONS = Option.ACTIONS + ("extend",)1917 STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)1918 TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)1919 ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)19201921 def take_action(self, action, dest, opt, value, values, parser):1922 if action == "extend":1923 lvalue = value.split(",")1924 values.ensure_value(dest, []).extend(lvalue)1925 else:1926 Option.take_action(1927 self, action, dest, opt, value, values, parser)1928```19291930Что следует отметить:19311932- `"extend"` одновременно ожидает значение в командной строке и сохраняет его, поэтому оно входит как в [`STORE_ACTIONS`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.STORE_ACTIONS), так и в [`TYPED_ACTIONS`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.TYPED_ACTIONS).1933- чтобы `optparse` назначал тип по умолчанию `"string"` для действий `"extend"`, мы также помещаем действие `"extend"` в [`ALWAYS_TYPED_ACTIONS`](https://python-all.ru/3.1/library/optparse.html#optparse.Option.ALWAYS_TYPED_ACTIONS).1934- `MyOption.take_action()` реализует только это одно новое действие и передаёт управление обратно `Option.take_action()` для стандартных действий `optparse`.1935- `values` – экземпляр класса optparse\_parser.Values, предоставляющий очень полезный метод `ensure_value()`. `ensure_value()` по сути [`getattr()`](https://python-all.ru/3.1/library/functions.html#getattr) с предохранительным клапаном; он вызывается как19361937 ```python1938 values.ensure_value(attr, value)1939 ```19401941 Если атрибут `attr` объекта `values` не существует или равен None, то ensure\_value() сначала устанавливает его в `value`, а затем возвращает value. Это очень удобно для таких действий, как `"extend"`, `"append"` и `"count"`, все они накапливают данные в переменной и ожидают, что эта переменная будет определённого типа (список для первых двух, целое число – для последнего). Использование `ensure_value()` означает, что скриптам, использующим ваше действие, не нужно беспокоиться об установке значения по умолчанию для соответствующих целевых опций; они могут просто оставить значение по умолчанию как None, и `ensure_value()` позаботится о правильной установке, когда это понадобится.1942