Документация Python неофициальный перевод

optparse.md

1542 строк · 126.5 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.7/library/optparse.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 15.5. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) – Парсер параметров командной строки89Новое в версии 2.3.1011Устарело с версии 2.7: Модуль [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) устарел и не будет развиваться дальше; разработка будет продолжена с модулем [`argparse`](https://python-all.ru/2.7/library/argparse.html#module-argparse).1213**Исходный код:** [Lib/optparse.py](https://python-all.ru/src/2.7/Lib/optparse.py)1415---1617[`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) – это более удобная, гибкая и мощная библиотека для разбора параметров командной строки, чем старый модуль [`getopt`](https://python-all.ru/2.7/library/getopt.html#module-getopt). [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) использует более декларативный стиль разбора командной строки: вы создаёте экземпляр [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser), заполняете его параметрами и разбираете командную строку. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) позволяет пользователям указывать параметры в стандартном синтаксисе GNU/POSIX, а также автоматически генерирует для вас сообщения об использовании и справку.1819Вот пример использования [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) в простом скрипте:2021```python22from optparse import OptionParser23...24parser = OptionParser()25parser.add_option("-f", "--file", dest="filename",26                  help="write report to FILE", metavar="FILE")27parser.add_option("-q", "--quiet",28                  action="store_false", dest="verbose", default=True,29                  help="don't print status messages to stdout")3031(options, args) = parser.parse_args()32```3334С помощью этих нескольких строк кода пользователи вашего скрипта теперь могут делать «обычные вещи» в командной строке, например:3536```python37<yourscript> --file=outfile -q38```3940По мере разбора командной строки [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) устанавливает атрибуты объекта `options`, возвращаемого `parse_args()`, на основе предоставленных пользователем значений командной строки. Когда `parse_args()` завершает разбор этой командной строки, `options.filename` будет `"outfile"`, а `options.verbose` будет `False`. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) поддерживает как длинные, так и короткие параметры, позволяет объединять короткие параметры, а также позволяет связывать параметры с их аргументами различными способами. Таким образом, следующие командные строки эквивалентны приведённому выше примеру:4142```python43<yourscript> -f outfile --quiet44<yourscript> --quiet --file outfile45<yourscript> -q -foutfile46<yourscript> -qfoutfile47```4849Кроме того, можно запустить один из5051```python52<yourscript> -h53<yourscript> --help54```5556и [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) выведет краткую сводку параметров вашего скрипта:5758```text59Usage: <yourscript> [options]6061Options:62  -h, --help            show this help message and exit63  -f FILE, --file=FILE  write report to FILE64  -q, --quiet           don't print status messages to stdout65```6667где значение *yourscript* определяется во время выполнения (обычно из `sys.argv[0]`).6869## 15.5.1. Общие сведения7071[`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) был явно спроектирован для поощрения создания программ с простыми и стандартными интерфейсами командной строки. Для этого он поддерживает только самые распространённые синтаксис и семантику командной строки, традиционно используемые в Unix. Если вы не знакомы с этими соглашениями, прочитайте этот раздел, чтобы ознакомиться с ними.7273### 15.5.1.1. Терминология7475**аргумент**7677строка, введенная в командной строке и переданная оболочкой в `execl()` или `execv()`. В Python аргументами являются элементы `sys.argv[1:]` (`sys.argv[0]` – это имя выполняемой программы). Оболочки Unix также используют термин «слово».7879Иногда желательно подставить список аргументов, отличный от `sys.argv[1:]`, поэтому под «аргументом» следует понимать «элемент `sys.argv[1:]` или любого другого списка, предоставленного взамен `sys.argv[1:]`».8081**опция**8283аргумент, используемый для передачи дополнительной информации, направляющей или настраивающей выполнение программы. Существует много различных синтаксисов для опций; традиционный синтаксис Unix – дефис («-») с последующей одной буквой, например `-x` или `-F`. Также традиционный синтаксис Unix позволяет объединять несколько опций в один аргумент, например `-x -F` эквивалентно `-xF`. Проект GNU ввёл `--`, за которым следует ряд слов, разделённых дефисами, например `--file` или `--dry-run`. Это единственные два синтаксиса опций, предоставляемые модулем [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse).8485Некоторые другие синтаксисы опций, которые встречались в мире, включают:8687- дефис с последующими несколькими буквами, например `-pf` (это *не* то же самое, что несколько опций, объединенных в один аргумент)88- дефис с последующим целым словом, например `-file` (технически это эквивалентно предыдущему синтаксису, но они обычно не встречаются в одной программе)89- знак плюс с последующей одной буквой, или несколькими буквами, или словом, например `+f`, `+rgb`90- косая черта с последующей буквой, или несколькими буквами, или словом, например `/f`, `/file`9192Эти синтаксисы опций не поддерживаются [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) и никогда не будут. Это сделано намеренно: первые три нестандартны в любом окружении, а последний имеет смысл только если вы ориентируетесь исключительно на VMS, MS-DOS и/или Windows.9394**аргумент опции**9596аргумент, который следует за опцией, тесно связан с этой опцией и извлекается из списка аргументов вместе с ней. В [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) аргументы опций могут находиться как в отдельном аргументе от своей опции:9798```text99-f foo100--file foo101```102103или включены в тот же аргумент:104105```text106-ffoo107--file=foo108```109110Обычно конкретная опция либо принимает аргумент, либо нет. Многие хотят функцию «необязательных аргументов опций», то есть некоторые опции будут принимать аргумент, если он есть, и не будут, если его нет. Это несколько спорно, поскольку делает разбор неоднозначным: если `-a` принимает необязательный аргумент, а `-b` – это совершенно другая опция, как интерпретировать `-ab`? Из-за этой неоднозначности [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) не поддерживает такую функцию.111112**позиционный аргумент**113114то, что осталось в списке аргументов после разбора опций, т.е. после того, как опции и их аргументы были разобраны и удалены из списка аргументов.115116**обязательная опция**117118опция, которая должна быть указана в командной строке; обратите внимание, что фраза «обязательная опция» противоречива по своей сути. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) не препятствует реализации обязательных опций, но и не оказывает большой помощи в этом.119120Например, рассмотрим эту гипотетическую командную строку:121122```python123prog -v --report report.txt foo bar124```125126`-v` и `--report` являются опциями. Предполагая, что `--report` принимает один аргумент, `report.txt` является аргументом опции. `foo` и `bar` являются позиционными аргументами.127128### 15.5.1.2. Для чего нужны опции?129130Опции используются для предоставления дополнительной информации для настройки или кастомизации выполнения программы. Если это не было очевидно, опции обычно *необязательны*. Программа должна нормально работать вообще без опций. (Возьмите случайную программу из инструментария Unix или GNU. Может ли она работать без каких-либо опций и при этом иметь смысл? Главные исключения – `find`, `tar` и `dd` – все они мутанты-чудаки, которые по праву критикуются за нестандартный синтаксис и запутанные интерфейсы.)131132Многие хотят, чтобы в их программах были «обязательные опции». Подумайте об этом. Если это обязательно, значит, это *не необязательно*! Если есть информация, которая absolutely необходима вашей программе для успешного выполнения, для этого существуют позиционные аргументы.133134В качестве примера хорошего дизайна интерфейса командной строки рассмотрим скромную утилиту `cp` для копирования файлов. Копировать файлы без указания назначения и хотя бы одного источника не имеет особого смысла. Поэтому `cp` завершается с ошибкой, если запустить ее без аргументов. Однако у нее гибкий, полезный синтаксис, который вообще не требует опций:135136```python137cp SOURCE DEST138cp SOURCE ... DEST-DIR139```140141На этом можно многого добиться. Большинство реализаций `cp` предоставляют множество опций для точной настройки копирования: можно сохранять права и время модификации, не следовать симлинкам, спрашивать перед перезаписью существующих файлов и т.д. Но ничто из этого не отвлекает от основной задачи `cp` – скопировать один файл в другой или несколько файлов в другой каталог.142143### 15.5.1.3. Для чего нужны позиционные аргументы?144145Позиционные аргументы предназначены для тех частей информации, которые absolutely и однозначно необходимы вашей программе для работы.146147Хороший пользовательский интерфейс должен иметь как можно меньше абсолютных требований. Если вашей программе требуется 17 различных частей информации для успешного запуска, не имеет большого значения *как* вы получаете эту информацию от пользователя – большинство людей сдадутся и уйдут, так и не запустив программу. Это справедливо независимо от того, является ли интерфейс командной строкой, файлом конфигурации или графическим интерфейсом: если вы предъявляете столько требований к пользователям, большинство из них просто сдадутся.148149Короче говоря, старайтесь минимизировать объем информации, которую пользователи absolutely обязаны предоставить – используйте разумные значения по умолчанию, когда это возможно. Конечно, вы также хотите сделать свои программы достаточно гибкими. Для этого и нужны опции. Опять же, неважно, являются ли они записями в файле конфигурации, виджетами в диалоге «Настройки» графического интерфейса или опциями командной строки – чем больше опций вы реализуете, тем гибче становится ваша программа, и тем сложнее становится ее реализация. Слишком большая гибкость тоже имеет недостатки; слишком много опций может перегрузить пользователей и сделать ваш код гораздо сложнее в поддержке.150151## 15.5.2. Учебное пособие152153Хотя [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) довольно гибкий и мощный, он также прост в использовании в большинстве случаев. В этом разделе рассматриваются шаблоны кода, общие для любой программы на основе [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse).154155Сначала необходимо импортировать класс OptionParser; затем, в начале основной программы, создать экземпляр OptionParser:156157```python158from optparse import OptionParser159...160parser = OptionParser()161```162163Затем можно приступить к определению опций. Базовый синтаксис:164165```python166parser.add_option(opt_str, ...,167                  attr=value, ...)168```169170Каждая опция имеет одну или несколько строк опций, например `-f` или `--file`, и несколько атрибутов, которые сообщают [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse), что ожидать и что делать, когда он встречает эту опцию в командной строке.171172Обычно каждая опция имеет одну короткую и одну длинную строку опции, например:173174```python175parser.add_option("-f", "--file", ...)176```177178Вы можете определить любое количество коротких и длинных строк опций (включая ноль), при условии, что в целом есть хотя бы одна строка опции.179180Строки опций, передаваемые в [`OptionParser.add_option()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.add_option), по сути являются метками для опции, определяемой этим вызовом. Для краткости мы часто будем ссылаться на *встречу опции* в командной строке; на самом деле [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) встречает *строки опций* и ищет опции по ним.181182Когда все опции определены, укажите [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) разобрать командную строку вашей программы:183184```python185(options, args) = parser.parse_args()186```187188(При желании можно передать собственный список аргументов в `parse_args()`, но это редко необходимо: по умолчанию он использует `sys.argv[1:]`.)189190`parse_args()` возвращает два значения:191192- `options` – объект, содержащий значения для всех опций. Например, если `--file` принимает один строковый аргумент, то `options.file` будет именем файла, указанным пользователем, или `None`, если пользователь не указал эту опцию.193- `args` – список позиционных аргументов, оставшихся после разбора опций194195В этом учебном разделе рассматриваются только четыре наиболее важных атрибута опций: [`action`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.action), [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type), [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) (destination) и [`help`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.help). Из них [`action`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.action) является самым основным.196197### 15.5.2.1. Действия опций198199Действия сообщают [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse), что делать, когда он встречает опцию в командной строке. Существует фиксированный набор действий, встроенных в [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse); добавление новых действий – продвинутая тема, рассматриваемая в разделе [Расширение optparse](https://python-all.ru/2.7/library/optparse.html#optparse-extending-optparse). Большинство действий говорят [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) сохранить значение в некоторую переменную – например, взять строку из командной строки и сохранить её в атрибуте `options`.200201Если не указано действие опции, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) по умолчанию использует `store`.202203### 15.5.2.2. Действие store204205Наиболее распространенное действие опции – `store`, которое говорит [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) взять следующий аргумент (или остаток текущего аргумента), убедиться, что он имеет правильный тип, и сохранить его в выбранное место назначения.206207Например:208209```python210parser.add_option("-f", "--file",211                  action="store", type="string", dest="filename")212```213214Теперь давайте создадим фиктивную командную строку и попросим [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) разобрать её:215216```python217args = ["-f", "foo.txt"]218(options, args) = parser.parse_args(args)219```220221Когда [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) видит строку опции `-f`, он потребляет следующий аргумент, `foo.txt`, и сохраняет его в `options.filename`. Итак, после этого вызова `parse_args()`, `options.filename` равно `"foo.txt"`.222223Некоторые другие типы опций, поддерживаемые [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse): `int` и `float`. Вот опция, которая ожидает целочисленный аргумент:224225```python226parser.add_option("-n", type="int", dest="num")227```228229Обратите внимание, что эта опция не имеет длинной строки опции, что вполне допустимо. Кроме того, отсутствует явное действие, поскольку по умолчанию используется `store`.230231Давайте разберём другую фиктивную командную строку. На этот раз мы поместим аргумент опции непосредственно рядом с опцией: поскольку `-n42` (один аргумент) эквивалентно `-n 42` (два аргумента), код232233```python234(options, args) = parser.parse_args(["-n42"])235print options.num236```237238выведет `42`.239240Если тип не указан, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) предполагает `string`. В сочетании с тем, что действие по умолчанию – `store`, это означает, что наш первый пример можно сделать гораздо короче:241242```python243parser.add_option("-f", "--file", dest="filename")244```245246Если место назначения не указано, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) определяет разумное значение по умолчанию из строк опций: если первая длинная строка опции – `--foo-bar`, то по умолчанию местом назначения будет `foo_bar`. Если длинных строк опций нет, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) смотрит на первую короткую строку опции: местом назначения по умолчанию для `-f` будет `f`.247248В модуль [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) также включены встроенные типы `long` и `complex`. Добавление типов описано в разделе [Расширение optparse](https://python-all.ru/2.7/library/optparse.html#optparse-extending-optparse).249250### 15.5.2.3. Обработка логических (флаговых) опций251252Флаговые опции – устанавливают переменную в true или false при обнаружении определённой опции – довольно распространены. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) поддерживает их с помощью двух отдельных действий: `store_true` и `store_false`. Например, у вас может быть флаг `verbose`, который включается с помощью `-v` и выключается с помощью `-q`:253254```python255parser.add_option("-v", action="store_true", dest="verbose")256parser.add_option("-q", action="store_false", dest="verbose")257```258259Здесь у нас две разные опции с одним и тем же назначением, что совершенно нормально. (Это просто означает, что нужно быть немного внимательнее при установке значений по умолчанию – см. ниже.)260261Когда [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) встречает `-v` в командной строке, он устанавливает `options.verbose` в `True`; когда он встречает `-q`, `options.verbose` устанавливается в `False`.262263### 15.5.2.4. Прочие действия264265Некоторые другие действия, поддерживаемые [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse):266267**`"store_const"`**268269сохранить константное значение270271**`"append"`**272273добавить аргумент этой опции в список274275**`"count"`**276277увеличить счётчик на единицу278279**`"callback"`**280281вызвать указанную функцию282283Эти вопросы рассматриваются в разделе [Справочное руководство](https://python-all.ru/2.7/library/optparse.html#optparse-reference-guide), Справочное руководство и разделе [Колбэки опций](https://python-all.ru/2.7/library/optparse.html#optparse-option-callbacks).284285### 15.5.2.5. Значения по умолчанию286287Все приведённые выше примеры предполагают установку некоторой переменной («назначения») при обнаружении определённых параметров командной строки. Что произойдёт, если эти параметры никогда не встретятся? Поскольку мы не указали значения по умолчанию, все они будут установлены в `None`. Обычно это нормально, но иногда требуется больший контроль. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) позволяет указать значение по умолчанию для каждого назначения, которое присваивается до разбора командной строки.288289Сначала рассмотрим пример с подробным/тихим режимом. Если мы хотим, чтобы [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) устанавливал `verbose` в `True`, если не встречен `-q`, то можно сделать так:290291```python292parser.add_option("-v", action="store_true", dest="verbose", default=True)293parser.add_option("-q", action="store_false", dest="verbose")294```295296Поскольку значения по умолчанию применяются к *назначению*, а не к какому-либо конкретному параметру, и эти два параметра имеют одно и то же назначение, это полностью эквивалентно:297298```python299parser.add_option("-v", action="store_true", dest="verbose")300parser.add_option("-q", action="store_false", dest="verbose", default=True)301```302303Рассмотрим это:304305```python306parser.add_option("-v", action="store_true", dest="verbose", default=False)307parser.add_option("-q", action="store_false", dest="verbose", default=True)308```309310Опять же, значение по умолчанию для `verbose` будет `True`: последнее указанное значение по умолчанию для любого конкретного назначения и будет использоваться.311312Более понятный способ задать значения по умолчанию – это метод `set_defaults()` объекта OptionParser, который можно вызывать в любое время до вызова `parse_args()`:313314```python315parser.set_defaults(verbose=True)316parser.add_option(...)317(options, args) = parser.parse_args()318```319320Как и прежде, последнее указанное значение для данного назначения параметра и будет использоваться. Для ясности старайтесь использовать какой-то один способ задания значений по умолчанию, а не оба сразу.321322### 15.5.2.6. Генерация справки323324Возможность [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) автоматически генерировать текст справки и использования полезна для создания удобных интерфейсов командной строки. Всё, что нужно сделать – указать значение [`help`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.help) для каждого параметра и, опционально, краткое сообщение об использовании для всей программы. Вот OptionParser, заполненный удобными (документированными) параметрами:325326```python327usage = "usage: %prog [options] arg1 arg2"328parser = OptionParser(usage=usage)329parser.add_option("-v", "--verbose",330                  action="store_true", dest="verbose", default=True,331                  help="make lots of noise [default]")332parser.add_option("-q", "--quiet",333                  action="store_false", dest="verbose",334                  help="be vewwy quiet (I'm hunting wabbits)")335parser.add_option("-f", "--filename",336                  metavar="FILE", help="write output to FILE")337parser.add_option("-m", "--mode",338                  default="intermediate",339                  help="interaction mode: novice, intermediate, "340                       "or expert [default: %default]")341```342343Если [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) встречает в командной строке `-h` или `--help`, или если просто вызвать `parser.print_help()`, он выводит следующее в стандартный вывод:344345```text346Usage: <yourscript> [options] arg1 arg2347348Options:349  -h, --help            show this help message and exit350  -v, --verbose         make lots of noise [default]351  -q, --quiet           be vewwy quiet (I'm hunting wabbits)352  -f FILE, --filename=FILE353                        write output to FILE354  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or355                        expert [default: intermediate]356```357358(Если вывод справки вызван опцией помощи, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) завершает работу после печати текста справки.)359360Здесь много деталей, помогающих [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) сгенерировать наилучшее сообщение справки:361362- сценарий определяет собственное сообщение об использовании:363364  ```python365  usage = "usage: %prog [options] arg1 arg2"366  ```367368  [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) заменяет `%prog` в строке использования на имя текущей программы, т.е. `os.path.basename(sys.argv[0])`. Затем расширенная строка выводится перед подробной справкой по параметрам.369370  Если не указать строку использования, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) использует простое, но разумное значение по умолчанию: `"Usage: %prog [options]"`, что подходит, если сценарий не принимает позиционные аргументы.371- каждая опция определяет строку справки, и не нужно беспокоиться о переносе строк – [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) заботится о переносе строк и делает вывод справки красивым.372- Опции, принимающие значение, указывают на это в автоматически сгенерированном сообщении справки, например, для опции «mode»:373374  ```python375  -m MODE, --mode=MODE376  ```377378  Здесь «MODE» называется метапеременной: она обозначает аргумент, который пользователь должен передать в `-m`/`--mode`. По умолчанию [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) преобразует имя переменной назначения в верхний регистр и использует его для метапеременной. Иногда это не то, что нужно – например, опция `--filename` явно задаёт `metavar="FILE"`, что приводит к такому автоматически сгенерированному описанию опции:379380  ```python381  -f FILE, --filename=FILE382  ```383384  Это важно не только для экономии места: вручную написанный текст справки использует мета-переменную `FILE`, чтобы подсказать пользователю, что существует связь между полуформальным синтаксисом `-f FILE` и неформальным семантическим описанием «записать вывод в FILE». Это простой, но эффективный способ сделать текст справки гораздо понятнее и полезнее для конечных пользователей.385386Новое в версии 2.4: Опции, имеющие значение по умолчанию, могут включать `%default` в строку справки – [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) заменит его на [`str()`](https://python-all.ru/2.7/library/functions.html#str) значения по умолчанию опции. Если опция не имеет значения по умолчанию (или значение по умолчанию равно `None`), `%default` раскрывается в `none`.387388#### 15.5.2.6.1. Группировка опций389390При работе с большим количеством параметров удобно группировать их для улучшения вывода справки. [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser) может содержать несколько групп параметров, каждая из которых может содержать несколько параметров.391392Группа параметров создаётся с помощью класса [`OptionGroup`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionGroup):393394#### `class optparse.OptionGroup(parser, title, description=None)`395396где397398- parser – это экземпляр [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser), в который будет вставлена группа399- title – это заголовок группы400- description (необязательно) – это подробное описание группы401402[`OptionGroup`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionGroup) наследуется от `OptionContainer` (как [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser)), поэтому метод `add_option()` можно использовать для добавления опции в группу.403404После объявления всех опций с помощью метода [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser) `add_option_group()` группа добавляется в ранее определённый парсер.405406Продолжая с парсером, определённым в предыдущем разделе, добавить [`OptionGroup`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionGroup) в парсер несложно:407408```python409group = OptionGroup(parser, "Dangerous Options",410                    "Caution: use these options at your own risk.  "411                    "It is believed that some of them bite.")412group.add_option("-g", action="store_true", help="Group option.")413parser.add_option_group(group)414```415416Это приведёт к следующему выводу справки:417418```text419Usage: <yourscript> [options] arg1 arg2420421Options:422  -h, --help            show this help message and exit423  -v, --verbose         make lots of noise [default]424  -q, --quiet           be vewwy quiet (I'm hunting wabbits)425  -f FILE, --filename=FILE426                        write output to FILE427  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or428                        expert [default: intermediate]429430  Dangerous Options:431    Caution: use these options at your own risk.  It is believed that some432    of them bite.433434    -g                  Group option.435```436437Несколько более полный пример может включать использование более одной группы: всё так же расширяя предыдущий пример:438439```python440group = OptionGroup(parser, "Dangerous Options",441                    "Caution: use these options at your own risk.  "442                    "It is believed that some of them bite.")443group.add_option("-g", action="store_true", help="Group option.")444parser.add_option_group(group)445446group = OptionGroup(parser, "Debug Options")447group.add_option("-d", "--debug", action="store_true",448                 help="Print debug information")449group.add_option("-s", "--sql", action="store_true",450                 help="Print all SQL statements executed")451group.add_option("-e", action="store_true", help="Print every action done")452parser.add_option_group(group)453```454455что приводит к следующему выводу:456457```text458Usage: <yourscript> [options] arg1 arg2459460Options:461  -h, --help            show this help message and exit462  -v, --verbose         make lots of noise [default]463  -q, --quiet           be vewwy quiet (I'm hunting wabbits)464  -f FILE, --filename=FILE465                        write output to FILE466  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or expert467                        [default: intermediate]468469  Dangerous Options:470    Caution: use these options at your own risk.  It is believed that some471    of them bite.472473    -g                  Group option.474475  Debug Options:476    -d, --debug         Print debug information477    -s, --sql           Print all SQL statements executed478    -e                  Print every action done479```480481Ещё один интересный метод, особенно при программной работе с группами опций:482483#### `OptionParser.get_option_group(opt_str)`484485Возвращает [`OptionGroup`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionGroup), которому принадлежит короткая или длинная строка опции *opt\_str* (например, `'-o'` или `'--option'`). Если такого [`OptionGroup`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionGroup) нет, возвращает `None`.486487### 15.5.2.7. Вывод строки версии488489Подобно краткой строке использования, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) также может выводить строку версии для программы. Строку нужно передать в качестве аргумента `version` конструктору OptionParser:490491```python492parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")493```494495`%prog` раскрывается так же, как в `usage`. Кроме того, `version` может содержать что угодно. При передаче строки [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) автоматически добавляет опцию `--version` в парсер. Если эта опция встречается в командной строке, строка `version` раскрывается (заменой `%prog`), выводится в stdout, и программа завершается.496497Например, если скрипт называется `/usr/bin/foo`:498499```console500$ /usr/bin/foo --version501foo 1.0502```503504Следующие два метода можно использовать для вывода и получения строки `version`:505506#### `OptionParser.print_version(file=None)`507508Выводит сообщение о версии текущей программы (`self.version`) в *file* (по умолчанию stdout). Как и в [`print_usage()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.print_usage), любое вхождение `%prog` в `self.version` заменяется на имя текущей программы. Ничего не делает, если `self.version` пусто или не определено.509510#### `OptionParser.get_version()`511512То же, что и [`print_version()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.print_version), но возвращает строку версии вместо её вывода.513514### 15.5.2.8. Как [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) обрабатывает ошибки515516Существует два широких класса ошибок, с которыми приходится иметь дело [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse): ошибки программиста и ошибки пользователя. Ошибки программиста – это обычно неверные вызовы [`OptionParser.add_option()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.add_option), например, некорректные строки опций, неизвестные атрибуты опций, отсутствующие атрибуты опций и т.д. Они обрабатываются обычным способом: возбуждается исключение (`optparse.OptionError` или [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError)), и программа завершается аварийно.517518Обработка ошибок пользователя гораздо важнее, поскольку они гарантированно возникают независимо от стабильности кода. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) может автоматически обнаруживать некоторые ошибки пользователя, такие как неверные аргументы опций (передача `-n 4x`, когда `-n` принимает целочисленный аргумент), отсутствие аргументов (`-n` в конце командной строки, когда `-n` принимает аргумент любого типа). Кроме того, можно вызвать `OptionParser.error()` для сигнализации об ошибке, определённой приложением:519520```python521(options, args) = parser.parse_args()522...523if options.a and options.b:524    parser.error("options -a and -b are mutually exclusive")525```526527В любом случае [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) обрабатывает ошибку одинаково: выводит сообщение об использовании программы и сообщение об ошибке в стандартный поток ошибок и завершается с кодом ошибки 2.528529Рассмотрим первый пример выше, где пользователь передаёт `4x` опции, которая принимает целое число:530531```console532$ /usr/bin/foo -n 4x533Usage: foo [options]534535foo: error: option -n: invalid integer value: '4x'536```537538Или когда пользователь вообще не передаёт значение:539540```console541$ /usr/bin/foo -n542Usage: foo [options]543544foo: error: -n option requires an argument545```546547Сообщения об ошибках, сгенерированные [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse), всегда содержат упоминание опции, вызвавшей ошибку; обязательно делайте то же самое при вызове `OptionParser.error()` из кода приложения.548549Если поведение обработки ошибок по умолчанию в [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) не соответствует требованиям, нужно создать подкласс OptionParser и переопределить его методы `exit()` и/или `error()`.550551### 15.5.2.9. Собираем всё вместе552553Вот как обычно выглядят скрипты на основе [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse):554555```python556from optparse import OptionParser557...558def main():559    usage = "usage: %prog [options] arg"560    parser = OptionParser(usage)561    parser.add_option("-f", "--file", dest="filename",562                      help="read data from FILENAME")563    parser.add_option("-v", "--verbose",564                      action="store_true", dest="verbose")565    parser.add_option("-q", "--quiet",566                      action="store_false", dest="verbose")567    ...568    (options, args) = parser.parse_args()569    if len(args) != 1:570        parser.error("incorrect number of arguments")571    if options.verbose:572        print "reading %s..." % options.filename573    ...574575if __name__ == "__main__":576    main()577```578579## 15.5.3. Справочное руководство580581### 15.5.3.1. Создание парсера582583Первым шагом при использовании [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) является создание экземпляра OptionParser.584585#### `class optparse.OptionParser(...)`586587Конструктор OptionParser не требует обязательных аргументов, но принимает ряд необязательных именованных аргументов. Их всегда следует передавать как именованные аргументы, т.е. не полагаться на порядок объявления аргументов.588589**`usage` (по умолчанию: `"%prog [options]"`)**590591Краткая справка по использованию, выводимая при неправильном запуске программы или по запросу справки. Когда [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) выводит строку использования, он заменяет `%prog` на `os.path.basename(sys.argv[0])` (или на `prog`, если был передан соответствующий именованный аргумент). Чтобы отключить сообщение об использовании, передайте специальное значение `optparse.SUPPRESS_USAGE`.592593**`option_list` (по умолчанию: `[]`)**594595Список объектов Option для заполнения парсера. Опции из `option_list` добавляются после любых опций из `standard_option_list` (атрибута класса, который может быть установлен подклассами OptionParser), но перед опциями версии и справки. Устарело; вместо этого используйте [`add_option()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.add_option) после создания парсера.596597**`option_class` (по умолчанию: optparse.Option)**598599Класс, используемый при добавлении опций в парсер в [`add_option()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.add_option).600601**`version` (по умолчанию: `None`)**602603Строка версии, выводимая по запросу опции версии. Если задать истинное значение для `version`, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) автоматически добавляет опцию версии с единственной строкой опции `--version`. Подстрока `%prog` заменяется так же, как для `usage`.604605**`conflict_handler` (по умолчанию: `"error"`)**606607Определяет, что делать, когда в парсер добавляются опции с конфликтующими строками опций; см. раздел [Конфликты между опциями](https://python-all.ru/2.7/library/optparse.html#optparse-conflicts-between-options).608609**`description` (по умолчанию: `None`)**610611Абзац текста с кратким обзором программы. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) переформатирует этот абзац под текущую ширину терминала и выводит его по запросу справки (после `usage`, но перед списком опций).612613**`formatter` (по умолчанию: новый `IndentedHelpFormatter`)**614615Экземпляр optparse.HelpFormatter, используемый для вывода текста справки. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) предоставляет два конкретных класса для этой цели: IndentedHelpFormatter и TitledHelpFormatter.616617**`add_help_option` (по умолчанию: `True`)**618619Если истина, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) добавит в парсер опцию справки (со строками опций `-h` и `--help`).620621**`prog`**622623Строка, используемая при замене `%prog` в `usage` и `version` вместо `os.path.basename(sys.argv[0])`.624625**`epilog` (по умолчанию: `None`)**626627Абзац текста справки, выводимый после справки по опциям.628629### 15.5.3.2. Заполнение парсера630631Есть несколько способов заполнить парсер опциями. Предпочтительный способ – использовать [`OptionParser.add_option()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.add_option), как показано в разделе [Учебное пособие](https://python-all.ru/2.7/library/optparse.html#optparse-tutorial). `add_option()` можно вызывать одним из двух способов:632633- передать ему экземпляр Option (как возвращается `make_option()`)634- передать ему любую комбинацию позиционных и именованных аргументов, приемлемую для `make_option()` (т.е. для конструктора Option), и он создаст экземпляр Option автоматически635636Другой способ – передать список предварительно созданных экземпляров Option конструктору OptionParser, например:637638```python639option_list = [640    make_option("-f", "--filename",641                action="store", type="string", dest="filename"),642    make_option("-q", "--quiet",643                action="store_false", dest="verbose"),644    ]645parser = OptionParser(option_list=option_list)646```647648(`make_option()` – фабричная функция для создания экземпляров Option; в настоящее время это псевдоним конструктора Option. Будущая версия [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) может разделить Option на несколько классов, и `make_option()` будет выбирать нужный класс для создания экземпляра. Не создавайте экземпляры Option напрямую.)649650### 15.5.3.3. Определение опций651652Каждый экземпляр Option представляет набор синонимичных строк опций командной строки, например `-f` и `--file`. Можно указать любое количество коротких или длинных строк опций, но необходимо указать хотя бы одну общую строку опции.653654Канонический способ создания экземпляра `Option` – это метод `add_option()` объекта [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser).655656#### `OptionParser.add_option(option)`657658#### `OptionParser.add_option(*opt_str, attr=value, ...)`659660Для определения опции только с короткой строкой опции:661662```python663parser.add_option("-f", attr=value, ...)664```665666А для определения опции только с длинной строкой опции:667668```python669parser.add_option("--foo", attr=value, ...)670```671672Именованные аргументы определяют атрибуты нового объекта Option. Самый важный атрибут опции – [`action`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.action), и он в значительной степени определяет, какие другие атрибуты являются релевантными или обязательными. Если передать нерелевантные атрибуты опции или не указать обязательные, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) вызовет исключение `OptionError`, поясняющее ошибку.673674Атрибут *action* опции определяет, что делает [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse), когда встречает эту опцию в командной строке. Стандартные действия опций, встроенные в [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse):675676**`"store"`**677678сохранить аргумент опции (по умолчанию)679680**`"store_const"`**681682сохранить константное значение683684**`"store_true"`**685686сохраняет истинное значение687688**`"store_false"`**689690сохраняет ложное значение691692**`"append"`**693694добавить аргумент этой опции в список695696**`"append_const"`**697698добавить константное значение в список699700**`"count"`**701702увеличить счётчик на единицу703704**`"callback"`**705706вызвать указанную функцию707708**`"help"`**709710вывести сообщение об использовании, включающее все опции и документацию к ним711712(Если не указать действие, по умолчанию используется `"store"`. Для этого действия можно также указать атрибуты опций [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) и [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest); см. [Стандартные действия опций](https://python-all.ru/2.7/library/optparse.html#optparse-standard-option-actions).)713714Как видите, большинство действий подразумевают сохранение или обновление значения где-либо. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) всегда создаёт для этого специальный объект, обычно называемый `options` (который является экземпляром `optparse.Values`). Аргументы опций (и различные другие значения) сохраняются как атрибуты этого объекта, согласно атрибуту опции [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) (назначение).715716Например, при вызове717718```python719parser.parse_args()720```721722одно из первых действий [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) – создание объекта `options`:723724```python725options = Values()726```727728Если одна из опций в этом анализаторе определена с помощью729730```python731parser.add_option("-f", "--file", action="store", type="string", dest="filename")732```733734и разбираемая командная строка включает любую из следующих:735736```python737-ffoo738-f foo739--file=foo740--file foo741```742743тогда [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse), увидев эту опцию, сделает эквивалент744745```python746options.filename = "foo"747```748749Атрибуты опций [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) и [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) почти так же важны, как [`action`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.action), но [`action`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.action) – единственный, который имеет смысл для *всех* опций.750751### 15.5.3.4. Атрибуты опций752753Следующие атрибуты опций могут быть переданы как именованные аргументы в [`OptionParser.add_option()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.add_option). Если передать атрибут опции, который не является релевантным для конкретной опции, или не указать обязательный атрибут опции, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) вызовет `OptionError`.754755#### `Option.action`756757(по умолчанию: `"store"`)758759Determines [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse)’s behaviour when this option is seen on the command line; the available options are documented [here](https://python-all.ru/2.7/library/optparse.html#optparse-standard-option-actions).760761#### `Option.type`762763(по умолчанию: `"string"`)764765The argument type expected by this option (e.g., `"string"` or `"int"`); the available option types are documented [here](https://python-all.ru/2.7/library/optparse.html#optparse-standard-option-types).766767#### `Option.dest`768769(по умолчанию: выводится из строк опций)770771Если действие опции подразумевает запись или изменение какого-либо значения, этот параметр указывает [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse), куда его записать: [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) задаёт имя атрибута объекта `options`, который [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) создаёт по мере разбора командной строки.772773#### `Option.default`774775Значение, используемое для целевого атрибута этой опции, если опция не встречена в командной строке. См. также [`OptionParser.set_defaults()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.set_defaults).776777#### `Option.nargs`778779(по умолчанию: 1)780781Сколько аргументов типа [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) должно быть потреблено, когда эта опция встречена. Если \> 1, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) сохранит кортеж значений в [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest).782783#### `Option.const`784785Для действий, сохраняющих постоянное значение, – само это постоянное значение.786787#### `Option.choices`788789Для опций типа `"choice"` – список строк, из которых пользователь может выбирать.790791#### `Option.callback`792793For options with action `"callback"`, the callable to call when this option is seen. See section [Option Callbacks](https://python-all.ru/2.7/library/optparse.html#optparse-option-callbacks) for detail on the arguments passed to the callable.794795#### `Option.callback_args`796797#### `Option.callback_kwargs`798799Дополнительные позиционные и именованные аргументы, передаваемые в `callback` после четырёх стандартных аргументов колбэка.800801#### `Option.help`802803Текст справки для этой опции, выводимый при перечислении всех доступных опций после того, как пользователь укажет опцию [`help`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.help) (например, `--help`). Если текст справки не указан, опция будет выведена без него. Чтобы скрыть опцию, используйте специальное значение `optparse.SUPPRESS_HELP`.804805#### `Option.metavar`806807(по умолчанию: выводится из строк опций)808809Stand-in for the option argument(s) to use when printing help text. See section [Tutorial](https://python-all.ru/2.7/library/optparse.html#optparse-tutorial) for an example.810811### 15.5.3.5. Стандартные действия опций812813Различные действия опций имеют слегка разные требования и эффекты. У большинства действий есть несколько соответствующих атрибутов опции, которые вы можете указать, чтобы управлять поведением [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse); некоторые имеют обязательные атрибуты, которые необходимо указывать для любой опции, использующей это действие.814815- `"store"` \[относится: [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type), [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest), [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs), [`choices`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.choices)\]816817  The option must be followed by an argument, which is converted to a value according to [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) and stored in [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest). If [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs) \> 1, multiple arguments will be consumed from the command line; all will be converted according to [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) and stored to [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) as a tuple. See the [Standard option types](https://python-all.ru/2.7/library/optparse.html#optparse-standard-option-types) section.818819  Если указан [`choices`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.choices) (список или кортеж строк), тип по умолчанию `"choice"`.820821  Если [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) не указан, по умолчанию используется `"string"`.822823  Если [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) не указан, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) выводит destination из первой длинной строки опции (например, `--foo-bar` подразумевает `foo_bar`). Если длинных строк опций нет, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) выводит destination из первой короткой строки опции (например, `-f` подразумевает `f`).824825  Пример:826827  ```python828  parser.add_option("-f")829  parser.add_option("-p", type="float", nargs=3, dest="point")830  ```831832  В процессе разбора командной строки833834  ```python835  -f foo.txt -p 1 -3.5 4 -fbar.txt836  ```837838  [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) установит839840  ```python841  options.f = "foo.txt"842  options.point = (1.0, -3.5, 4.0)843  options.f = "bar.txt"844  ```845- `"store_const"` \[обязательно: [`const`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.const); относится: [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest)\]846847  Значение [`const`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.const) сохраняется в [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest).848849  Пример:850851  ```python852  parser.add_option("-q", "--quiet",853                    action="store_const", const=0, dest="verbose")854  parser.add_option("-v", "--verbose",855                    action="store_const", const=1, dest="verbose")856  parser.add_option("--noisy",857                    action="store_const", const=2, dest="verbose")858  ```859860  Если встречается `--noisy`, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) установит861862  ```python863  options.verbose = 2864  ```865- `"store_true"` \[относится: [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest)\]866867  Особый случай `"store_const"`, который сохраняет истинное значение в [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest).868- `"store_false"` \[относится: [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest)\]869870  Как и `"store_true"`, но сохраняет ложное значение.871872  Пример:873874  ```python875  parser.add_option("--clobber", action="store_true", dest="clobber")876  parser.add_option("--no-clobber", action="store_false", dest="clobber")877  ```878- `"append"` \[относится: [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type), [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest), [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs), [`choices`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.choices)\]879880  За опцией должен следовать аргумент, который добавляется в список [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest). Если значение по умолчанию для [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) не указано, пустой список автоматически создаётся, когда [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) впервые встречает эту опцию в командной строке. Если [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs) \> 1, потребляется несколько аргументов, и кортеж длины [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs) добавляется в [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest).881882  Значения по умолчанию для [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) и [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) такие же, как для действия `"store"`.883884  Пример:885886  ```python887  parser.add_option("-t", "--tracks", action="append", type="int")888  ```889890  Если в командной строке встречается `-t3`, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) делает то же самое, что:891892  ```python893  options.tracks = []894  options.tracks.append(int("3"))895  ```896897  Если чуть позже встречается `--tracks=4`, выполняется:898899  ```python900  options.tracks.append(int("4"))901  ```902903  Действие `append` вызывает метод `append` для текущего значения опции. Это означает, что любое указанное значение по умолчанию должно иметь метод `append`. Это также означает, что если значение по умолчанию непустое, элементы по умолчанию будут присутствовать в разобранном значении для опции, а любые значения из командной строки будут добавлены после этих значений по умолчанию:904905  ```python906  >>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults'])907  >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg'])908  >>> opts.files909  ['~/.mypkg/defaults', 'overrides.mypkg']910  ```911- `"append_const"` \[обязательно: [`const`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.const); относится: [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest)\]912913  Как `"store_const"`, но значение [`const`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.const) добавляется в [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest); как и в `"append"`, [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) по умолчанию равен `None`, и пустой список автоматически создаётся при первом обнаружении опции.914- `"count"` \[относится: [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest)\]915916  Увеличивает целое число, хранящееся в [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest). Если значение по умолчанию не указано, [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest) устанавливается в ноль перед первым увеличением.917918  Пример:919920  ```python921  parser.add_option("-v", action="count", dest="verbosity")922  ```923924  При первом появлении `-v` в командной строке [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) делает то же самое, что:925926  ```python927  options.verbosity = 0928  options.verbosity += 1929  ```930931  Каждое последующее появление `-v` приводит к932933  ```python934  options.verbosity += 1935  ```936- `"callback"` \[обязательно: [`callback`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback); относится: [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type), [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs), [`callback_args`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_args), [`callback_kwargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_kwargs)\]937938  Вызывает функцию, указанную в [`callback`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback), которая вызывается как939940  ```python941  func(option, opt_str, value, parser, *args, **kwargs)942  ```943944  Смотрите раздел [Колбэки опций](https://python-all.ru/2.7/library/optparse.html#optparse-option-callbacks) для подробностей.945- `"help"`946947  Выводит полное справочное сообщение для всех опций текущего парсера опций. Справочное сообщение формируется из строки `usage`, переданной конструктору OptionParser, и строки [`help`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.help), переданной каждой опции.948949  Если для опции не указана строка [`help`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.help), она всё равно будет перечислена в справочном сообщении. Чтобы полностью исключить опцию, используйте специальное значение `optparse.SUPPRESS_HELP`.950951  [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) автоматически добавляет опцию [`help`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.help) для всех объектов OptionParser, поэтому обычно не требуется создавать его отдельно.952953  Пример:954955  ```python956  from optparse import OptionParser, SUPPRESS_HELP957958  # обычно опция справки добавляется автоматически, но её можно959  # подавить, используя аргумент add_help_option960  parser = OptionParser(add_help_option=False)961962  parser.add_option("-h", "--help", action="help")963  parser.add_option("-v", action="store_true", dest="verbose",964                    help="Be moderately verbose")965  parser.add_option("--file", dest="filename",966                    help="Input file to read data from")967  parser.add_option("--secret", help=SUPPRESS_HELP)968  ```969970  Если [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) обнаруживает в командной строке `-h` или `--help`, он выводит примерно такое справочное сообщение в stdout (при условии, что `sys.argv[0]` равно `"foo.py"`):971972  ```text973  Usage: foo.py [options]974975  Options:976    -h, --help        Show this help message and exit977    -v                Be moderately verbose978    --file=FILENAME   Input file to read data from979  ```980981  После вывода справочного сообщения [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) завершает процесс с кодом `sys.exit(0)`.982- `"version"`983984  Выводит номер версии, переданный OptionParser, в stdout и завершает работу. Номер версии форматируется и выводится методом `print_version()` объекта OptionParser. Обычно актуально только если аргумент `version` передан конструктору OptionParser. Как и для опций [`help`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.help), `version` редко создаются вручную, так как [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) добавляет их автоматически при необходимости.985986### 15.5.3.6. Стандартные типы опций987988Модуль [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) имеет шесть встроенных типов опций: `"string"`, `"int"`, `"long"`, `"choice"`, `"float"` и `"complex"`. Если нужно добавить новые типы опций, смотрите раздел [Расширение optparse](https://python-all.ru/2.7/library/optparse.html#optparse-extending-optparse).989990Аргументы строковых опций никак не проверяются и не преобразуются: текст из командной строки сохраняется в целевом атрибуте (или передаётся колбэку) как есть.991992Целочисленные аргументы (тип `"int"` или `"long"`) разбираются следующим образом:993994- если число начинается с `0x`, оно разбирается как шестнадцатеричное995- если число начинается с `0`, оно разбирается как восьмеричное996- если число начинается с `0b`, оно разбирается как двоичное997- в противном случае число разбирается как десятичное998999Преобразование выполняется вызовом [`int()`](https://python-all.ru/2.7/library/functions.html#int) или [`long()`](https://python-all.ru/2.7/library/functions.html#long) с соответствующим основанием (2, 8, 10 или 16). Если это не удаётся, то [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) также завершится ошибкой, хотя с более полезным сообщением об ошибке.10001001Аргументы опций `"float"` и `"complex"` преобразуются напрямую с помощью [`float()`](https://python-all.ru/2.7/library/functions.html#float) и [`complex()`](https://python-all.ru/2.7/library/functions.html#complex), с аналогичной обработкой ошибок.10021003Опции `"choice"` являются подтипом опций `"string"`. Атрибут опции [`choices`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.choices) (последовательность строк) определяет набор допустимых аргументов опции. `optparse.check_choice()` сравнивает предоставленные пользователем аргументы опции с этим основным списком и возбуждает `OptionValueError`, если указана недопустимая строка.10041005### 15.5.3.7. Разбор аргументов10061007Весь смысл создания и заполнения OptionParser заключается в вызове его метода `parse_args()`:10081009```python1010(options, args) = parser.parse_args(args=None, values=None)1011```10121013где входные параметры:10141015**`args`**10161017список аргументов для обработки (по умолчанию: `sys.argv[1:]`)10181019**`values`**10201021объект `optparse.Values` для хранения аргументов параметров (по умолчанию: новый экземпляр `Values`) – если передать существующий объект, значения параметров по умолчанию не будут в нем инициализированы10221023а возвращаемые значения –10241025**`options`**10261027тот же объект, который был передан как `values`, или экземпляр optparse.Values, созданный [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse)10281029**`args`**10301031оставшиеся позиционные аргументы после обработки всех опций10321033Наиболее распространённый способ использования – не указывать ни один из именованных аргументов. Если передать `values`, он будет изменён многократными вызовами [`setattr()`](https://python-all.ru/2.7/library/functions.html#setattr) (примерно по одному на каждый аргумент опции, сохраняемый в целевой атрибут) и возвращён `parse_args()`.10341035Если `parse_args()` обнаруживает ошибки в списке аргументов, он вызывает метод `error()` объекта OptionParser с подходящим сообщением об ошибке для конечного пользователя. В итоге процесс завершается с кодом возврата 2 (традиционный код выхода Unix для ошибок командной строки).10361037### 15.5.3.8. Запросы и манипуляции с анализатором параметров10381039Поведение парсера опций по умолчанию можно слегка настроить, а также можно заглянуть внутрь парсера и посмотреть, что там есть. OptionParser предоставляет несколько методов, которые в этом помогут:10401041#### `OptionParser.disable_interspersed_args()`10421043Настраивает разбор на остановку при первом не-опции. Например, если `-a` и `-b` – простые опции, не принимающие аргументов, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) обычно принимает такой синтаксис:10441045```python1046prog -a arg1 -b arg21047```10481049и обрабатывает его как эквивалент10501051```python1052prog -a -b arg1 arg21053```10541055Чтобы отключить эту возможность, вызовите [`disable_interspersed_args()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.disable_interspersed_args). Это восстанавливает традиционный синтаксис Unix, где разбор опций останавливается на первом аргументе, не являющемся опцией.10561057Используйте это, если у вас есть обработчик команд, который запускает другую команду с собственными опциями, и нужно гарантировать, что эти опции не будут перепутаны. Например, каждая команда может иметь свой набор опций.10581059#### `OptionParser.enable_interspersed_args()`10601061Настраивает разбор на то, чтобы не останавливаться на первом не-опции, позволяя перемешивать ключи с аргументами команды. Это поведение по умолчанию.10621063#### `OptionParser.get_option(opt_str)`10641065Возвращает экземпляр Option с строкой опции *opt\_str* или `None`, если ни одна опция не имеет такой строки.10661067#### `OptionParser.has_option(opt_str)`10681069Возвращает True, если OptionParser имеет опцию со строкой опции *opt\_str* (например, `-q` или `--verbose`).10701071#### `OptionParser.remove_option(opt_str)`10721073Если [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser) имеет опцию, соответствующую *opt\_str*, эта опция удаляется. Если эта опция предоставляла какие-либо другие строки опций, все эти строки опций становятся недействительными. Если *opt\_str* не встречается ни в одной опции, принадлежащей этому [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser), возбуждается [`ValueError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.ValueError).10741075### 15.5.3.9. Конфликты между опциями10761077Если быть невнимательным, легко определить опции с конфликтующими строками опций:10781079```python1080parser.add_option("-n", "--dry-run", ...)1081...1082parser.add_option("-n", "--noisy", ...)1083```10841085(Это особенно актуально, если определён собственный подкласс OptionParser с некоторыми стандартными опциями.)10861087При каждом добавлении опции [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) проверяет наличие конфликтов с существующими опциями. Если они обнаружены, вызывается текущий механизм обработки конфликтов. Механизм обработки конфликтов можно задать либо в конструкторе:10881089```python1090parser = OptionParser(..., conflict_handler=handler)1091```10921093или отдельным вызовом:10941095```python1096parser.set_conflict_handler(handler)1097```10981099Доступные обработчики конфликтов:11001101> **`"error"` (по умолчанию)**1102>1103> считать конфликты опций программной ошибкой и возбуждать `OptionConflictError`1104>1105> **`"resolve"`**1106>1107> разрешать конфликты опций интеллектуально (см. ниже)11081109В качестве примера определим [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser), который разрешает конфликты интеллектуально, и добавим к нему конфликтующие опции:11101111```python1112parser = OptionParser(conflict_handler="resolve")1113parser.add_option("-n", "--dry-run", ..., help="do no harm")1114parser.add_option("-n", "--noisy", ..., help="be noisy")1115```11161117На этом этапе [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) обнаруживает, что ранее добавленная опция уже использует строку опции `-n`. Поскольку `conflict_handler` является `"resolve"`, он разрешает ситуацию, удаляя `-n` из списка строк опций более ранней опции. Теперь `--dry-run` – единственный способ для пользователя активировать эту опцию. Если пользователь запросит справку, сообщение справки отразит это:11181119```python1120Options:1121  --dry-run     do no harm1122  ...1123  -n, --noisy   be noisy1124```11251126Можно сокращать строки опций для ранее добавленной опции до тех пор, пока их не останется, и у пользователя не будет способа вызвать эту опцию из командной строки. В этом случае [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) полностью удаляет эту опцию, так что она не появляется в тексте справки или где-либо ещё. Продолжая с нашим существующим OptionParser:11271128```python1129parser.add_option("--dry-run", ..., help="new dry-run option")1130```11311132На этом этапе исходная опция `-n`/`--dry-run` больше не доступна, поэтому [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) удаляет её, оставляя такой текст справки:11331134```python1135Options:1136  ...1137  -n, --noisy   be noisy1138  --dry-run     new dry-run option1139```11401141### 15.5.3.10. Очистка11421143Экземпляры OptionParser содержат несколько циклических ссылок. Это не должно быть проблемой для сборщика мусора Python, но можно явно разорвать циклические ссылки, вызвав `destroy()` для вашего OptionParser после завершения работы с ним. Это особенно полезно в долго работающих приложениях, где из OptionParser достижимы большие графы объектов.11441145### 15.5.3.11. Другие методы11461147OptionParser поддерживает несколько других открытых методов:11481149#### `OptionParser.set_usage(usage)`11501151Устанавливает строку использования в соответствии с правилами, описанными выше для аргумента конструктора `usage`. Передача `None` устанавливает строку использования по умолчанию; используйте `optparse.SUPPRESS_USAGE`, чтобы подавить сообщение об использовании.11521153#### `OptionParser.print_usage(file=None)`11541155Выводит сообщение об использовании для текущей программы (`self.usage`) в *file* (по умолчанию stdout). Любое вхождение строки `%prog` в `self.usage` заменяется именем текущей программы. Ничего не делает, если `self.usage` пусто или не определено.11561157#### `OptionParser.get_usage()`11581159То же, что и [`print_usage()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.print_usage), но возвращает строку использования вместо её вывода.11601161#### `OptionParser.set_defaults(dest=value, ...)`11621163Устанавливает значения по умолчанию для нескольких целевых параметров опций одновременно. Использование [`set_defaults()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.set_defaults) является предпочтительным способом установки значений по умолчанию для опций, поскольку несколько опций могут совместно использовать один и тот же целевой параметр. Например, если несколько опций «режим» устанавливают один и тот же целевой параметр, любая из них может задать значение по умолчанию, и последняя имеет преимущество:11641165```python1166parser.add_option("--advanced", action="store_const",1167                  dest="mode", const="advanced",1168                  default="novice")    # переопределено ниже1169parser.add_option("--novice", action="store_const",1170                  dest="mode", const="novice",1171                  default="advanced")  # переопределяет вышеуказанную настройку1172```11731174Чтобы избежать этой путаницы, используйте [`set_defaults()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.set_defaults):11751176```python1177parser.set_defaults(mode="advanced")1178parser.add_option("--advanced", action="store_const",1179                  dest="mode", const="advanced")1180parser.add_option("--novice", action="store_const",1181                  dest="mode", const="novice")1182```11831184## 15.5.4. Колбэки опций11851186Когда встроенных действий и типов [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) недостаточно, есть два варианта: расширить [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) или определить опцию-колбэк. Расширение [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) более универсально, но для многих простых случаев избыточно. Зачастую простого колбэка вполне достаточно.11871188Определение опции-колбэка состоит из двух шагов:11891190- определить саму опцию с помощью действия `"callback"`1191- написать колбэк – функцию (или метод), которая принимает как минимум четыре аргумента, как описано ниже11921193### 15.5.4.1. Определение опции с колбэком11941195Как всегда, проще всего определить опцию-колбэк с помощью метода [`OptionParser.add_option()`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser.add_option). Кроме [`action`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.action), единственный атрибут опции, который необходимо указать, – это `callback`, вызываемая функция:11961197```python1198parser.add_option("-c", action="callback", callback=my_callback)1199```12001201`callback` – это функция (или другой вызываемый объект), поэтому к моменту создания опции-колбэка `my_callback()` должна быть уже определена. В этом простом случае [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) даже не знает, принимает ли `-c` какие-либо аргументы, что обычно означает, что опция не принимает аргументов – достаточно одного присутствия `-c` в командной строке. Однако в некоторых ситуациях может потребоваться, чтобы колбэк обрабатывал произвольное количество аргументов командной строки. Здесь написание колбэков становится сложнее; об этом рассказывается далее в этом разделе.12021203[`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) всегда передаёт колбэку четыре определённых аргумента и передаёт дополнительные, только если они указаны через [`callback_args`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_args) и [`callback_kwargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_kwargs). Таким образом, минимальная сигнатура функции колбэка выглядит так:12041205```python1206def my_callback(option, opt, value, parser):1207```12081209Четыре аргумента колбэка описаны ниже.12101211Есть ещё несколько атрибутов опции, которые можно указать при определении опции-колбэка:12121213**[`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type)**12141215имеет обычный смысл: как и действия `"store"` или `"append"`, он указывает [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) потребить один аргумент и преобразовать его в [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type). Однако вместо сохранения преобразованного значения где-либо, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) передаёт его функции колбэка.12161217**[`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs)**12181219также имеет обычный смысл: если он указан и больше 1, [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) потребит [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs) аргументов, каждый из которых должен быть преобразуем в [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type). Затем он передаёт колбэку кортеж преобразованных значений.12201221**[`callback_args`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_args)**12221223кортеж дополнительных позиционных аргументов, передаваемых колбэку12241225**[`callback_kwargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_kwargs)**12261227словарь дополнительных именованных аргументов, передаваемых колбэку12281229### 15.5.4.2. Как вызываются колбэки12301231Все колбэки вызываются следующим образом:12321233```python1234func(option, opt_str, value, parser, *args, **kwargs)1235```12361237где12381239**`option`**12401241это экземпляр Option, который вызывает колбэк12421243**`opt_str`**12441245это строка опции, указанная в командной строке, которая запускает колбэк. (Если использовалась сокращённая длинная опция, `opt_str` будет полной канонической строкой опции – например, если пользователь ввёл `--foo` в командной строке как сокращение для `--foobar`, то `opt_str` будет `"--foobar"`.)12461247**`value`**12481249это аргумент данной опции, указанный в командной строке. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) будет ожидать аргумент, только если установлен [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type); тип `value` будет типом, подразумеваемым типом опции. Если [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type) для этой опции равно `None` (аргумент не ожидается), то `value` будет `None`. Если [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs) \> 1, `value` будет кортежем значений соответствующего типа.12501251**`parser`**12521253это экземпляр OptionParser, управляющий всем процессом; он полезен тем, что через его атрибуты можно получить доступ к некоторым другим интересным данным:12541255**`parser.largs`**12561257текущий список оставшихся аргументов, то есть аргументов, которые были потреблены, но не являются ни опциями, ни аргументами опций. `parser.largs` можно изменять, например, добавляя в него новые аргументы. (Этот список станет `args`, вторым возвращаемым значением `parse_args()`.)12581259**`parser.rargs`**12601261текущий список оставшихся аргументов, то есть после удаления `opt_str` и `value` (если применимо), в котором остались только следующие за ними аргументы. `parser.rargs` можно изменять, например, потребляя дополнительные аргументы.12621263**`parser.values`**12641265объект, в котором по умолчанию хранятся значения опций (экземпляр optparse.OptionValues). Это позволяет колбэкам использовать тот же механизм хранения значений опций, что и остальная часть [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse); не нужно возиться с глобальными переменными или замыканиями. Также можно получать или изменять значения любых опций, уже встреченных в командной строке.12661267**`args`**12681269это кортеж произвольных позиционных аргументов, переданных через атрибут опции [`callback_args`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_args).12701271**`kwargs`**12721273это словарь произвольных именованных аргументов, переданных через [`callback_kwargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.callback_kwargs).12741275### 15.5.4.3. Генерация ошибок в колбэке12761277Функция колбэка должна возбуждать `OptionValueError` при любых проблемах с опцией или её аргументами. [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) перехватывает это исключение и завершает программу, выводя сообщение об ошибке, указанное вами, в stderr. Сообщение должно быть ясным, кратким, точным и содержать указание на опцию, вызвавшую ошибку. В противном случае пользователю будет сложно понять, что он сделал не так.12781279### 15.5.4.4. Пример колбэка 1: тривиальный колбэк12801281Вот пример опции-колбэка, которая не принимает аргументов и просто записывает факт своего появления:12821283```python1284def record_foo_seen(option, opt_str, value, parser):1285    parser.values.saw_foo = True12861287parser.add_option("--foo", action="callback", callback=record_foo_seen)1288```12891290Конечно, это можно было бы сделать с помощью действия `"store_true"`.12911292### 15.5.4.5. Пример колбэка 2: проверка порядка опций12931294Вот чуть более интересный пример: запоминать, что `-a` был замечен, но завершаться с ошибкой, если он встречается после `-b` в командной строке.12951296```python1297def check_order(option, opt_str, value, parser):1298    if parser.values.b:1299        raise OptionValueError("can't use -a after -b")1300    parser.values.a = 11301...1302parser.add_option("-a", action="callback", callback=check_order)1303parser.add_option("-b", action="store_true", dest="b")1304```13051306### 15.5.4.6. Пример колбэка 3: проверка порядка опций (обобщённая)13071308Если требуется повторно использовать этот колбэк для нескольких похожих опций (устанавливать флаг, но выдавать ошибку, если `-b` уже был обработан), потребуется доработка: сообщение об ошибке и устанавливаемый флаг должны быть обобщены.13091310```python1311def check_order(option, opt_str, value, parser):1312    if parser.values.b:1313        raise OptionValueError("can't use %s after -b" % opt_str)1314    setattr(parser.values, option.dest, 1)1315...1316parser.add_option("-a", action="callback", callback=check_order, dest='a')1317parser.add_option("-b", action="store_true", dest="b")1318parser.add_option("-c", action="callback", callback=check_order, dest='c')1319```13201321### 15.5.4.7. Пример колбэка 4: проверка произвольного условия13221323Конечно, можно задать любое условие – вы не ограничены проверкой значений уже определённых параметров. Например, если есть параметры, которые не должны вызываться в полнолуние, достаточно сделать так:13241325```python1326def check_moon(option, opt_str, value, parser):1327    if is_moon_full():1328        raise OptionValueError("%s option invalid when moon is full"1329                               % opt_str)1330    setattr(parser.values, option.dest, 1)1331...1332parser.add_option("--foo",1333                  action="callback", callback=check_moon, dest="foo")1334```13351336(Определение `is_moon_full()` оставляется читателю в качестве упражнения.)13371338### 15.5.4.8. Пример колбэка 5: фиксированные аргументы13391340Ситуация становится немного интереснее, когда определяется параметр-колбэк с фиксированным числом аргументов. Указание, что параметр-колбэк принимает аргументы, аналогично определению параметра `"store"` или `"append"`: если задано [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type), то параметр принимает один аргумент, который должен быть преобразуем к этому типу; если дополнительно задано [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs), то параметр принимает [`nargs`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.nargs) аргументов.13411342Вот пример, который просто эмулирует стандартное действие `"store"`:13431344```python1345def store_value(option, opt_str, value, parser):1346    setattr(parser.values, option.dest, value)1347...1348parser.add_option("--foo",1349                  action="callback", callback=store_value,1350                  type="int", nargs=3, dest="foo")1351```13521353Обратите внимание, что [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) сам заботится о потреблении 3 аргументов и преобразовании их в целые числа; остаётся только сохранить их. (Или что угодно; очевидно, для этого примера колбэк не нужен.)13541355### 15.5.4.9. Пример колбэка 6: переменные аргументы13561357Всё становится сложнее, когда требуется, чтобы параметр принимал переменное число аргументов. В этом случае нужно писать колбэк, так как [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) не предоставляет встроенных средств для этого. И придётся разбираться с определёнными тонкостями традиционного разбора командной строки Unix, которые [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) обычно обрабатывает автоматически. В частности, колбэки должны реализовывать обычные правила для голых аргументов `--` и `-`:13581359- как `--`, так и `-` могут быть аргументами параметра1360- голый `--` (если не является аргументом какого-либо параметра): остановить обработку командной строки и отбросить `--`1361- голый `-` (если не является аргументом какого-либо параметра): остановить обработку командной строки, но сохранить `-` (добавить его к `parser.largs`)13621363Если нужен параметр, принимающий переменное число аргументов, возникает несколько тонких и сложных моментов. Конкретная реализация будет зависеть от того, на какие компромиссы вы готовы пойти для своего приложения (именно поэтому [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) не поддерживает такое напрямую).13641365Тем не менее, вот пример попытки создать колбэк для параметра с переменным числом аргументов:13661367```python1368def vararg_callback(option, opt_str, value, parser):1369    assert value is None1370    value = []13711372    def floatable(str):1373        try:1374            float(str)1375            return True1376        except ValueError:1377            return False13781379    for arg in parser.rargs:1380        # останавливаться на опциях вида --foo1381        if arg[:2] == "--" and len(arg) > 2:1382            break1383        # останавливаться на -a, но не на -3 или -3.01384        if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):1385            break1386        value.append(arg)13871388    del parser.rargs[:len(value)]1389    setattr(parser.values, option.dest, value)13901391...1392parser.add_option("-c", "--callback", dest="vararg_attr",1393                  action="callback", callback=vararg_callback)1394```13951396## 15.5.5. Расширение [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse)13971398Поскольку двумя основными управляющими факторами того, как [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) интерпретирует параметры командной строки, являются действие и тип каждого параметра, наиболее вероятное направление расширения – добавление новых действий и новых типов.13991400### 15.5.5.1. Добавление новых типов14011402Чтобы добавить новые типы, нужно определить собственный подкласс класса `Option` из [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse). У этого класса есть пара атрибутов, определяющих типы [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse): [`TYPES`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.TYPES) и [`TYPE_CHECKER`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.TYPE_CHECKER).14031404#### `Option.TYPES`14051406Кортеж имён типов; в своём подклассе просто определите новый кортеж [`TYPES`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.TYPES), основанный на стандартном.14071408#### `Option.TYPE_CHECKER`14091410Словарь, отображающий имена типов в функции проверки типа. Функция проверки типа имеет следующую сигнатуру:14111412```python1413def check_mytype(option, opt, value)1414```14151416где `option` – это экземпляр `Option`, `opt` – строка параметра (например, `-f`), а `value` – строка из командной строки, которую нужно проверить и преобразовать в желаемый тип. `check_mytype()` должна возвращать объект гипотетического типа `mytype`. Значение, возвращаемое функцией проверки типа, окажется в экземпляре OptionValues, возвращаемом `OptionParser.parse_args()`, или будет передано колбэку как параметр `value`.14171418Функция проверки типа должна возбуждать `OptionValueError` при возникновении проблем. `OptionValueError` принимает единственный строковый аргумент, который передаётся как есть методу `error()` объекта [`OptionParser`](https://python-all.ru/2.7/library/optparse.html#optparse.OptionParser), который, в свою очередь, добавляет имя программы и строку `"error:"` и печатает всё в stderr перед завершением процесса.14191420Вот глуповатый пример, демонстрирующий добавление типа параметра `"complex"` для разбора комплексных чисел в стиле Python в командной строке. (Этот пример стал ещё глупее, чем был, потому что в [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) 1.3 добавлена встроенная поддержка комплексных чисел, но не будем обращать внимания.)14211422Сначала необходимые импорты:14231424```python1425from copy import copy1426from optparse import Option, OptionValueError1427```14281429Сначала нужно определить проверщик типов, так как на него будет ссылка позже (в атрибуте класса [`TYPE_CHECKER`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.TYPE_CHECKER) вашего подкласса Option):14301431```python1432def check_complex(option, opt, value):1433    try:1434        return complex(value)1435    except ValueError:1436        raise OptionValueError(1437            "option %s: invalid complex value: %r" % (opt, value))1438```14391440Наконец, подкласс Option:14411442```python1443class MyOption (Option):1444    TYPES = Option.TYPES + ("complex",)1445    TYPE_CHECKER = copy(Option.TYPE_CHECKER)1446    TYPE_CHECKER["complex"] = check_complex1447```14481449(Если бы мы не создали [`copy()`](https://python-all.ru/2.7/library/copy.html#module-copy) для [`Option.TYPE_CHECKER`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.TYPE_CHECKER), мы бы в итоге изменили атрибут [`TYPE_CHECKER`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.TYPE_CHECKER) класса Option из [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse). Поскольку это Python, ничто не мешает это сделать, кроме хороших манер и здравого смысла.)14501451Вот и всё! Теперь можно написать скрипт, использующий новый тип опции, точно так же, как и любой другой скрипт на основе [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse), за исключением того, что нужно указать своему OptionParser использовать MyOption вместо Option:14521453```python1454parser = OptionParser(option_class=MyOption)1455parser.add_option("-c", type="complex")1456```14571458Либо можно собрать собственный список опций и передать его в OptionParser; если не использовать `add_option()` описанным выше способом, не требуется сообщать OptionParser, какой класс опции использовать:14591460```python1461option_list = [MyOption("-c", action="store", type="complex", dest="c")]1462parser = OptionParser(option_list=option_list)1463```14641465### 15.5.5.2. Добавление новых действий14661467Добавление новых действий немного сложнее, потому что нужно понимать, что [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) разделяет действия на несколько категорий:14681469**«store»-действия**14701471действия, в результате которых [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) сохраняет значение в атрибут текущего экземпляра OptionValues; для таких опций в конструктор Option требуется передать атрибут [`dest`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.dest).14721473**«typed»-действия**14741475действия, которые берут значение из командной строки и ожидают, что оно будет определённого типа; точнее, ожидают строку, которую можно преобразовать в заданный тип. Для таких опций в конструктор Option требуется передать атрибут [`type`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.type).14761477Это пересекающиеся множества: к стандартным «store»-действиям относятся `"store"`, `"store_const"`, `"append"` и `"count"`, а к стандартным «typed»-действиям – `"store"`, `"append"` и `"callback"`.14781479При добавлении действия его нужно отнести к категории, включив как минимум в один из следующих атрибутов класса Option (все они являются списками строк):14801481#### `Option.ACTIONS`14821483Все действия должны быть перечислены в ACTIONS.14841485#### `Option.STORE_ACTIONS`14861487«store»-действия дополнительно перечисляются здесь.14881489#### `Option.TYPED_ACTIONS`14901491«typed»-действия дополнительно перечисляются здесь.14921493#### `Option.ALWAYS_TYPED_ACTIONS`14941495Действия, которые всегда принимают тип (то есть их опции всегда получают значение), дополнительно перечисляются здесь. Единственный эффект этого состоит в том, что [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) назначает тип по умолчанию `"string"` опциям без явно указанного типа, чьё действие перечислено в [`ALWAYS_TYPED_ACTIONS`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.ALWAYS_TYPED_ACTIONS).14961497Чтобы реализовать новое действие, нужно переопределить метод `take_action()` класса Option и добавить ветвь, распознающую это действие.14981499Например, добавим действие `"extend"`. Оно похоже на стандартное `"append"`, но вместо того, чтобы взять из командной строки одно значение и добавить его в конец существующего списка, `"extend"` принимает несколько значений в одной строке с разделителями-запятыми и расширяет ими существующий список. То есть, если `--names` является опцией `"extend"` с типом `"string"`, то командная строка15001501```python1502--names=foo,bar --names blah --names ding,dong1503```15041505приведёт к списку15061507```python1508["foo", "bar", "blah", "ding", "dong"]1509```15101511Снова определим подкласс Option:15121513```python1514class MyOption(Option):15151516    ACTIONS = Option.ACTIONS + ("extend",)1517    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)1518    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)1519    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)15201521    def take_action(self, action, dest, opt, value, values, parser):1522        if action == "extend":1523            lvalue = value.split(",")1524            values.ensure_value(dest, []).extend(lvalue)1525        else:1526            Option.take_action(1527                self, action, dest, opt, value, values, parser)1528```15291530Что следует отметить:15311532- `"extend"` одновременно ожидает значение в командной строке и сохраняет его, поэтому попадает как в [`STORE_ACTIONS`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.STORE_ACTIONS), так и в [`TYPED_ACTIONS`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.TYPED_ACTIONS).1533- чтобы [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse) назначал тип по умолчанию `"string"` действиям `"extend"`, мы помещаем действие `"extend"` также в [`ALWAYS_TYPED_ACTIONS`](https://python-all.ru/2.7/library/optparse.html#optparse.Option.ALWAYS_TYPED_ACTIONS).1534- `MyOption.take_action()` реализует только это одно новое действие и передаёт управление обратно `Option.take_action()` для стандартных действий [`optparse`](https://python-all.ru/2.7/library/optparse.html#module-optparse).1535- `values` – это экземпляр класса optparse\_parser.Values, предоставляющий очень полезный метод `ensure_value()`. `ensure_value()` – это по сути [`getattr()`](https://python-all.ru/2.7/library/functions.html#getattr) с предохранительным клапаном; он вызывается как15361537  ```python1538  values.ensure_value(attr, value)1539  ```15401541  Если атрибут `attr` объекта `values` не существует или равен `None`, то ensure\_value() сначала устанавливает его в `value`, а затем возвращает значение. Это очень удобно для действий вроде `"extend"`, `"append"` и `"count"`, все из которых накапливают данные в переменной и ожидают, что переменная будет определённого типа (список для первых двух, целое число для последнего). Использование `ensure_value()` означает, что сценарии, использующие ваше действие, могут не беспокоиться об установке значения по умолчанию для соответствующих мест назначения опций; они могут просто оставить значение по умолчанию равным `None`, и `ensure_value()` позаботится о том, чтобы всё было правильно, когда это потребуется.1542