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

optparse.md

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

1> **Источник:** https://python-all.ru/3.0/library/optparse.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `optparse` – более мощный парсер опций командной строки89`optparse` – более удобная, гибкая и мощная библиотека для разбора опций командной строки, чем старый модуль [`getopt`](https://python-all.ru/3.0/library/getopt.html#module-getopt). `optparse` использует более декларативный стиль разбора командной строки: создаётся экземпляр `OptionParser`, заполняется опциями и выполняется разбор командной строки. `optparse` позволяет пользователям задавать опции в традиционном синтаксисе GNU/POSIX, а также автоматически генерирует сообщения об использовании и справку.1011Вот пример использования `optparse` в простом скрипте:1213```python14from optparse import OptionParser15[...]16parser = OptionParser()17parser.add_option("-f", "--file", dest="filename",18                  help="write report to FILE", metavar="FILE")19parser.add_option("-q", "--quiet",20                  action="store_false", dest="verbose", default=True,21                  help="don't print status messages to stdout")2223(options, args) = parser.parse_args()24```2526С помощью этих нескольких строк кода пользователи вашего скрипта теперь могут делать «обычные вещи» в командной строке, например:2728```python29<yourscript> --file=outfile -q30```3132При разборе командной строки `optparse` устанавливает атрибуты объекта `options`, возвращаемого функцией `parse_args()`, на основе значений, указанных пользователем в командной строке. Когда `parse_args()` завершает разбор, `options.filename` будет равно `"outfile"`, а `options.verbose``False`. `optparse` поддерживает как длинные, так и короткие опции, позволяет объединять короткие опции и связывать опции с их аргументами различными способами. Таким образом, следующие командные строки эквивалентны приведённому выше примеру:3334```python35<yourscript> -f outfile --quiet36<yourscript> --quiet --file outfile37<yourscript> -q -foutfile38<yourscript> -qfoutfile39```4041Кроме того, можно запустить один из4243```python44<yourscript> -h45<yourscript> --help46```4748и `optparse` выведет краткую сводку опций вашего скрипта:4950```python51usage: <yourscript> [options]5253options:54  -h, --help            show this help message and exit55  -f FILE, --file=FILE  write report to FILE56  -q, --quiet           don't print status messages to stdout57```5859где значение *yourscript* определяется во время выполнения (обычно из `sys.argv[0]`).6061## Предыстория6263`optparse` был разработан специально для поощрения создания программ с простыми и общепринятыми интерфейсами командной строки. Для этого он поддерживает только наиболее распространённый синтаксис и семантику командной строки, традиционно используемые в Unix. Если вы не знакомы с этими соглашениями, прочтите этот раздел, чтобы ознакомиться с ними.6465### Терминология6667**аргумент**6869строка, введённая в командной строке и переданная оболочкой в `execl()` или `execv()`. В Python аргументы являются элементами `sys.argv[1:]` (`sys.argv[0]` – это имя выполняемой программы). В Unix-оболочках также используется термин «слово».7071Иногда требуется подставить список аргументов, отличный от `sys.argv[1:]`, поэтому следует понимать «аргумент» как «элемент `sys.argv[1:]` или какого-либо другого списка, предоставленного вместо `sys.argv[1:]`».7273**опция**7475аргумент, используемый для предоставления дополнительной информации для управления или настройки выполнения программы. Существует множество различных синтаксисов опций; традиционный синтаксис Unix – дефис («-») с последующей одной буквой, например `"-x"` или `"-F"`. Кроме того, традиционный синтаксис Unix позволяет объединять несколько опций в один аргумент, например `"-x -F"` эквивалентно `"-xF"`. Проект GNU ввёл `"--"` с последующей последовательностью слов, разделённых дефисами, например `"--file"` или `"--dry-run"`. Это единственные два синтаксиса опций, поддерживаемые `optparse`.7677Некоторые другие синтаксисы опций, которые встречались в мире, включают:7879- дефис, за которым следует несколько букв, например `"-pf"` (это *не* то же самое, что несколько опций, объединённых в один аргумент)80- дефис, за которым следует целое слово, например `"-file"` (технически это эквивалентно предыдущему синтаксису, но они обычно не встречаются в одной программе)81- знак плюс, за которым следует одна буква, несколько букв или слово, например `"+f"`, `"+rgb"`82- косая черта, за которой следует буква, несколько букв или слово, например `"/f"`, `"/file"`8384Эти синтаксисы опций не поддерживаются `optparse` и никогда не будут. Это сделано намеренно: первые три нестандартны в любом окружении, а последний имеет смысл только в том случае, если программа ориентирована исключительно на VMS, MS-DOS и/или Windows.8586**аргумент опции**8788аргумент, который следует за опцией, тесно связан с этой опцией и извлекается из списка аргументов вместе с ней. В `optparse` аргументы опций могут находиться как в отдельном аргументе от своей опции:8990```python91-f foo92--file foo93```9495или включены в тот же аргумент:9697```python98-ffoo99--file=foo100```101102Обычно у опции либо есть аргумент, либо нет. Многие хотят иметь возможность «необязательных аргументов опции», то есть некоторые опции будут принимать аргумент, если он есть, и не будут, если его нет. Это несколько спорно, потому что делает разбор неоднозначным: если `"-a"` принимает необязательный аргумент, а `"-b"` – это совсем другая опция, как интерпретировать `"-ab"`? Из-за этой неоднозначности `optparse` не поддерживает такую возможность.103104**позиционный аргумент**105106то, что остаётся в списке аргументов после разбора опций, то есть после того, как опции и их аргументы были разобраны и удалены из списка аргументов.107108**обязательная опция**109110опция, которая должна быть указана в командной строке; обратите внимание, что фраза «обязательная опция» внутренне противоречива.111112`optparse`113114не препятствует реализации обязательных опций, но и не особо помогает в этом. См.115116`examples/required_1.py`117118и119120`examples/required_2.py`121122в дистрибутиве исходного кода123124`optparse`125126для двух способов реализации обязательных опций с помощью127128`optparse`129130.131132Например, рассмотрим эту гипотетическую командную строку:133134```python135prog -v --report /tmp/report.txt foo bar136```137138`"-v"` и `"--report"` – это опции. Если предположить, что *--report* принимает один аргумент, то `"/tmp/report.txt"` – это аргумент опции. `"foo"` и `"bar"` – это позиционные аргументы.139140### Для чего нужны опции?141142Опции используются для предоставления дополнительной информации для настройки или кастомизации выполнения программы. На всякий случай, если это не было очевидно: опции обычно *необязательны*. Программа должна нормально работать вообще без опций. (Выберите случайную программу из набора Unix или GNU. Может ли она работать вообще без опций и при этом иметь смысл? Основные исключения – `find`, `tar` и `dd` – все они являются мутантными чудаками, которые справедливо критикуются за нестандартный синтаксис и запутанные интерфейсы.)143144Многие хотят, чтобы в их программах были «обязательные опции». Подумайте об этом. Если это обязательно, значит, это *не необязательно*! Если есть информация, которая absolutely необходима вашей программе для успешного выполнения, для этого существуют позиционные аргументы.145146В качестве примера хорошего дизайна интерфейса командной строки рассмотрим скромную утилиту `cp` для копирования файлов. Не имеет особого смысла пытаться копировать файлы без указания назначения и хотя бы одного источника. Следовательно, `cp` завершается ошибкой, если запустить её без аргументов. Однако у неё гибкий, полезный синтаксис, который вообще не требует никаких опций:147148```python149cp SOURCE DEST150cp SOURCE ... DEST-DIR151```152153С этим можно зайти довольно далеко. Большинство реализаций `cp` предоставляют множество опций для точной настройки копирования: можно сохранять режим и время изменения, избегать следования симлинкам, спрашивать подтверждение перед перезаписью существующих файлов и т.д. Но ничто из этого не отвлекает от основной миссии `cp`, которая состоит в копировании одного файла в другой или нескольких файлов в другой каталог.154155### Для чего нужны позиционные аргументы?156157Позиционные аргументы предназначены для тех частей информации, которые absolutely и однозначно необходимы вашей программе для работы.158159Хороший пользовательский интерфейс должен иметь как можно меньше абсолютных требований. Если вашей программе требуется 17 различных частей информации для успешного запуска, не имеет большого значения *как* вы получаете эту информацию от пользователя – большинство людей сдадутся и уйдут, так и не запустив программу. Это справедливо независимо от того, является ли интерфейс командной строкой, файлом конфигурации или графическим интерфейсом: если вы предъявляете столько требований к пользователям, большинство из них просто сдадутся.160161Короче говоря, старайтесь минимизировать объем информации, которую пользователи absolutely обязаны предоставить – используйте разумные значения по умолчанию, когда это возможно. Конечно, вы также хотите сделать свои программы достаточно гибкими. Для этого и нужны опции. Опять же, неважно, являются ли они записями в файле конфигурации, виджетами в диалоге «Настройки» графического интерфейса или опциями командной строки – чем больше опций вы реализуете, тем гибче становится ваша программа, и тем сложнее становится ее реализация. Слишком большая гибкость тоже имеет недостатки; слишком много опций может перегрузить пользователей и сделать ваш код гораздо сложнее в поддержке.162163## Учебное руководство164165Хотя `optparse` довольно гибок и мощен, в большинстве случаев он достаточно прост в использовании. В этом разделе рассматриваются шаблоны кода, общие для любой программы на основе `optparse`.166167Сначала необходимо импортировать класс OptionParser; затем, в начале основной программы, создать экземпляр OptionParser:168169```python170from optparse import OptionParser171[...]172parser = OptionParser()173```174175Затем можно приступить к определению опций. Базовый синтаксис:176177```python178parser.add_option(opt_str, ...,179                  attr=value, ...)180```181182Каждая опция имеет одну или несколько строк опции, например `"-f"` или `"--file"`, и несколько атрибутов опции, которые сообщают `optparse`, чего ожидать и что делать, когда он встречает эту опцию в командной строке.183184Обычно каждая опция имеет одну короткую и одну длинную строку опции, например:185186```python187parser.add_option("-f", "--file", ...)188```189190Вы можете определить любое количество коротких и длинных строк опций (включая ноль), при условии, что в целом есть хотя бы одна строка опции.191192Строки опций, передаваемые в `add_option()`, по сути являются метками для опции, определённой этим вызовом. Для краткости мы часто будем говорить о *встрече опции* в командной строке; на самом деле `optparse` встречает *строки опций* и ищет по ним опции.193194Когда все опции определены, укажите `optparse` разобрать командную строку вашей программы:195196```python197(options, args) = parser.parse_args()198```199200(При желании можно передать собственный список аргументов в `parse_args()`, но это редко бывает необходимо: по умолчанию используется `sys.argv[1:]`.)201202`parse_args()` возвращает два значения:203204- `options` – объект, содержащий значения для всех опций; например, если `"--file"` принимает единственный строковой аргумент, то `options.file` будет именем файла, указанным пользователем, или `None`, если пользователь не указал эту опцию.205- `args` – список позиционных аргументов, оставшихся после разбора опций.206207В этом разделе руководства рассматриваются только четыре наиболее важных атрибута опции: `action`, [`type`](https://python-all.ru/3.0/library/functions.html#type), `dest` (назначение) и [`help`](https://python-all.ru/3.0/library/functions.html#help). Из них `action` является основным.208209### Понимание действий опций210211Действия сообщают `optparse`, что делать, когда он встречает опцию в командной строке. Существует фиксированный набор действий, жёстко заданный в `optparse`; добавление новых действий – продвинутая тема, рассматриваемая в разделе [*Расширение optparse*](https://python-all.ru/3.0/library/optparse.html#optparse-extending-optparse). Большинство действий указывают `optparse` сохранить значение в некоторой переменной – например, взять строку из командной строки и сохранить её в атрибуте `options`.212213Если не указать действие опции, `optparse` по умолчанию использует `store`.214215### Действие store216217Наиболее распространённое действие опции – `store`, которое указывает `optparse` взять следующий аргумент (или остаток текущего аргумента), убедиться, что он имеет правильный тип, и сохранить его в выбранное вами назначение.218219Например:220221```python222parser.add_option("-f", "--file",223                  action="store", type="string", dest="filename")224```225226Теперь создадим фиктивную командную строку и попросим `optparse` разобрать её:227228```python229args = ["-f", "foo.txt"]230(options, args) = parser.parse_args(args)231```232233Когда `optparse` видит строку опции `"-f"`, он потребляет следующий аргумент, `"foo.txt"`, и сохраняет его в `options.filename`. Итак, после этого вызова `parse_args()` `options.filename` равно `"foo.txt"`.234235Некоторые другие типы опций, поддерживаемые `optparse`: `int` и `float`. Вот опция, ожидающая целочисленный аргумент:236237```python238parser.add_option("-n", type="int", dest="num")239```240241Обратите внимание, что эта опция не имеет длинной строки опции, что вполне допустимо. Кроме того, нет явного действия, поскольку по умолчанию используется `store`.242243Разберём ещё одну тестовую командную строку. На этот раз поместим аргумент опции непосредственно рядом с опцией: поскольку `"-n42"` (один аргумент) эквивалентно `"-n 42"` (два аргумента), код244245```python246(options, args) = parser.parse_args(["-n42"])247print(options.num)248```249250выведет `"42"`.251252Если не указать тип, `optparse` предполагает `string`. В сочетании с тем, что действие по умолчанию – `store`, это означает, что наш первый пример можно значительно сократить:253254```python255parser.add_option("-f", "--file", dest="filename")256```257258Если не указать назначение, `optparse` определяет разумное значение по умолчанию из строк опции: если первой длинной строкой опции является `"--foo-bar"`, то назначением по умолчанию будет `foo_bar`. Если длинных строк опции нет, `optparse` смотрит на первую короткую строку опции: назначение по умолчанию для `"-f"``f`.259260`optparse` также включает встроенный тип `complex`. Добавление типов описано в разделе [*Extending optparse*](https://python-all.ru/3.0/library/optparse.html#optparse-extending-optparse).261262### Обработка булевых (флаговых) опций263264Опции-флаги – установка переменной в true или false при встрече определённой опции – довольно распространены. `optparse` поддерживает их с помощью двух отдельных действий: `store_true` и `store_false`. Например, может быть флаг `verbose`, который включается с помощью `"-v"` и выключается с помощью `"-q"`:265266```python267parser.add_option("-v", action="store_true", dest="verbose")268parser.add_option("-q", action="store_false", dest="verbose")269```270271Здесь у нас две разные опции с одним и тем же назначением, что совершенно нормально. (Это просто означает, что нужно быть немного внимательнее при установке значений по умолчанию – см. ниже.)272273Когда `optparse` встречает `"-v"` в командной строке, он устанавливает `options.verbose` в `True`; при встрече `"-q"` `options.verbose` устанавливается в `False`.274275### Другие действия276277Некоторые другие действия, поддерживаемые `optparse`:278279**`store_const`**280281сохранить константное значение282283**`append`**284285добавить аргумент этой опции в список286287**`count`**288289увеличить счётчик на единицу290291**`колбэк`**292293вызвать указанную функцию294295Эти вопросы рассматриваются в разделе [*Справочное руководство*](https://python-all.ru/3.0/library/optparse.html#optparse-reference-guide), Справочное руководство и разделе [*Колбэки опций*](https://python-all.ru/3.0/library/optparse.html#optparse-option-callbacks).296297### Значения по умолчанию298299Все приведённые выше примеры подразумевают установку некоторой переменной (так называемого «назначения») при встрече определённых параметров командной строки. Что произойдёт, если эти параметры ни разу не встретятся? Поскольку мы не указали значения по умолчанию, все они будут установлены в `None`. Обычно это нормально, но иногда хочется большего контроля. `optparse` позволяет указать значение по умолчанию для каждого назначения; оно присваивается до разбора командной строки.300301Сначала рассмотрим пример verbose/quiet. Если нужно, чтобы `optparse` устанавливал `verbose` в `True`, если только не встретится `"-q"`, то можно сделать следующее:302303```python304parser.add_option("-v", action="store_true", dest="verbose", default=True)305parser.add_option("-q", action="store_false", dest="verbose")306```307308Поскольку значения по умолчанию применяются к *назначению*, а не к какому-либо конкретному параметру, и эти два параметра имеют одно и то же назначение, это полностью эквивалентно:309310```python311parser.add_option("-v", action="store_true", dest="verbose")312parser.add_option("-q", action="store_false", dest="verbose", default=True)313```314315Рассмотрим это:316317```python318parser.add_option("-v", action="store_true", dest="verbose", default=False)319parser.add_option("-q", action="store_false", dest="verbose", default=True)320```321322Опять же, значение по умолчанию для `verbose` будет `True`: последнее значение по умолчанию, указанное для любого конкретного назначения, считается окончательным.323324Более понятный способ указать значения по умолчанию – метод `set_defaults()` класса OptionParser, который можно вызвать в любое время до вызова `parse_args()`:325326```python327parser.set_defaults(verbose=True)328parser.add_option(...)329(options, args) = parser.parse_args()330```331332Как и прежде, последнее указанное значение для данного назначения параметра и будет использоваться. Для ясности старайтесь использовать какой-то один способ задания значений по умолчанию, а не оба сразу.333334### Генерация справки335336Возможность `optparse` автоматически создавать текст справки и описание использования полезна для создания удобных интерфейсов командной строки. Всё, что нужно сделать, – указать значение [`help`](https://python-all.ru/3.0/library/functions.html#help) для каждой опции и, при желании, краткое сообщение об использовании для всей программы. Вот OptionParser, заполненный удобными (документированными) опциями:337338```python339usage = "usage: %prog [options] arg1 arg2"340parser = OptionParser(usage=usage)341parser.add_option("-v", "--verbose",342                  action="store_true", dest="verbose", default=True,343                  help="make lots of noise [default]")344parser.add_option("-q", "--quiet",345                  action="store_false", dest="verbose",346                  help="be vewwy quiet (I'm hunting wabbits)")347parser.add_option("-f", "--filename",348                  metavar="FILE", help="write output to FILE"),349parser.add_option("-m", "--mode",350                  default="intermediate",351                  help="interaction mode: novice, intermediate, "352                       "or expert [default: %default]")353```354355Если `optparse` встречает в командной строке `"-h"` или `"--help"`, или если просто вызвать `parser.print_help()`, он выводит следующее на стандартный вывод:356357```python358usage: <yourscript> [options] arg1 arg2359360options:361  -h, --help            show this help message and exit362  -v, --verbose         make lots of noise [default]363  -q, --quiet           be vewwy quiet (I'm hunting wabbits)364  -f FILE, --filename=FILE365                        write output to FILE366  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or367                        expert [default: intermediate]368```369370(Если вывод справки вызван параметром помощи, `optparse` завершает работу после печати текста справки.)371372Здесь задействовано много всего, чтобы помочь `optparse` сгенерировать наилучшее сообщение справки:373374- сценарий определяет собственное сообщение об использовании:375376  ```python377  usage = "usage: %prog [options] arg1 arg2"378  ```379380  `optparse` заменяет `"%prog"` в строке использования на имя текущей программы, то есть `os.path.basename(sys.argv[0])`. Затем расширенная строка выводится перед подробной справкой по опциям.381382  Если строка usage не указана, `optparse` использует стандартное, но вполне разумное значение: `"usage: %prog [options]"`. Это подходит, если скрипт не принимает позиционные аргументы.383- каждый параметр определяет строку справки, и не нужно беспокоиться о переносе строк – `optparse` заботится о переносе строк и о том, чтобы вывод справки выглядел хорошо.384- Опции, принимающие значение, указывают на это в автоматически сгенерированном сообщении справки, например, для опции «mode»:385386  ```python387  -m MODE, --mode=MODE388  ```389390  Здесь «MODE» называется мета-переменной: она обозначает аргумент, который пользователь должен передать [*-m*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-m)/*--mode*. По умолчанию `optparse` преобразует имя переменной назначения в верхний регистр и использует его для мета-переменной. Иногда это не то, что нужно – например, опция *--filename* явно задаёт `metavar="FILE"`, что приводит к следующему автоматически сгенерированному описанию опции:391392  ```python393  -f FILE, --filename=FILE394  ```395396  Это важно не только для экономии места: написанный вручную текст справки использует мета-переменную «FILE», чтобы дать пользователю понять, что существует связь между полуформальным синтаксисом «-f FILE» и неформальным семантическим описанием «write output to FILE». Это простой, но эффективный способ сделать текст справки значительно понятнее и полезнее для конечных пользователей.397- параметры, имеющие значение по умолчанию, могут включать `%default` в строку справки – `optparse` заменит его на [`str()`](https://python-all.ru/3.0/library/functions.html#str) от значения по умолчанию параметра. Если у параметра нет значения по умолчанию (или значение по умолчанию – `None`), `%default` разворачивается в `none`.398399При работе с большим количеством опций удобно группировать их для улучшения вывода справки. Один `OptionParser` может содержать несколько групп опций, каждая из которых может включать несколько опций.400401Продолжая работать с анализатором, определённым выше, добавить `OptionGroup` в анализатор очень просто:402403```python404group = OptionGroup(parser, "Dangerous Options",405                    "Caution: use these options at your own risk.  "406                    "It is believed that some of them bite.")407group.add_option("-g", action="store_true", help="Group option.")408parser.add_option_group(group)409```410411Это приведёт к следующему выводу справки:412413```python414usage:  [options] arg1 arg2415416options:417  -h, --help           show this help message and exit418  -v, --verbose        make lots of noise [default]419  -q, --quiet          be vewwy quiet (I'm hunting wabbits)420  -fFILE, --file=FILE  write output to FILE421  -mMODE, --mode=MODE  interaction mode: one of 'novice', 'intermediate'422                       [default], 'expert'423424  Dangerous Options:425  Caution: use of these options is at your own risk.  It is believed that426  some of them bite.427  -g                 Group option.428```429430### Печать строки версии431432Подобно краткой строке использования, `optparse` также может выводить строку версии для вашей программы. Нужно указать эту строку в качестве аргумента `version` для OptionParser:433434```python435parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")436```437438`"%prog"` is expanded just like it is in `usage`. Apart from that, `version` can contain anything you like. When you supply it, `optparse` automatically adds a `"--version"` option to your parser. If it encounters this option on the command line, it expands your `version` string (by replacing `"%prog"`), prints it to stdout, and exits.439440Например, если ваш скрипт называется `/usr/bin/foo`:441442```python443$ /usr/bin/foo --version444foo 1.0445```446447### Как `optparse` обрабатывает ошибки448449`optparse` имеет дело с двумя широкими классами ошибок: ошибками программиста и ошибками пользователя. Ошибки программиста обычно возникают из-за некорректных вызовов `parser.add_option()`, например, недопустимые строки опций, неизвестные атрибуты опций, отсутствующие атрибуты и т.д. Они обрабатываются обычным способом: выбрасывается исключение (`optparse.OptionError` или [`TypeError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.TypeError)), и программа завершается крахом.450451Обработка ошибок пользователя гораздо важнее, поскольку они гарантированно будут возникать независимо от стабильности кода. `optparse` может автоматически обнаруживать некоторые ошибки пользователя, такие как неверные аргументы опций (передача `"-n 4x"`, где *-n* ожидает целочисленный аргумент), отсутствие аргументов (`"-n"` в конце командной строки, где *-n* принимает аргумент любого типа). Кроме того, можно вызвать `parser.error()`, чтобы сообщить об ошибке, определённой приложением:452453```python454(options, args) = parser.parse_args()455[...]456if options.a and options.b:457    parser.error("options -a and -b are mutually exclusive")458```459460В любом случае `optparse` обрабатывает ошибку одинаково: выводит справку по использованию программы и сообщение об ошибке в стандартный поток ошибок и завершается с кодом ошибки 2.461462Рассмотрим первый пример выше, где пользователь передаёт `"4x"` опции, ожидающей целое число:463464```python465$ /usr/bin/foo -n 4x466usage: foo [options]467468foo: error: option -n: invalid integer value: '4x'469```470471Или когда пользователь вообще не передаёт значение:472473```python474$ /usr/bin/foo -n475usage: foo [options]476477foo: error: -n option requires an argument478```479480Сообщения об ошибках, сгенерированные `optparse`, всегда указывают опцию, связанную с ошибкой; обязательно делайте то же самое при вызове `parser.error()` из кода приложения.481482Если поведение `optparse` по умолчанию при обработке ошибок не соответствует вашим требованиям, потребуется создать подкласс OptionParser и переопределить его методы [`exit()`](https://python-all.ru/3.0/library/constants.html#exit) и/или `error()`.483484### Собираем всё вместе485486Вот как обычно выглядят сценарии на основе `optparse`:487488```python489from optparse import OptionParser490[...]491def main():492    usage = "usage: %prog [options] arg"493    parser = OptionParser(usage)494    parser.add_option("-f", "--file", dest="filename",495                      help="read data from FILENAME")496    parser.add_option("-v", "--verbose",497                      action="store_true", dest="verbose")498    parser.add_option("-q", "--quiet",499                      action="store_false", dest="verbose")500    [...]501    (options, args) = parser.parse_args()502    if len(args) != 1:503        parser.error("incorrect number of arguments")504    if options.verbose:505        print("reading %s..." % options.filename)506    [...]507508if __name__ == "__main__":509    main()510```511512## Справочное руководство513514### Создание парсера515516Первый шаг в использовании `optparse` – создание экземпляра OptionParser:517518```python519parser = OptionParser(...)520```521522Конструктор OptionParser не имеет обязательных аргументов, но принимает ряд необязательных именованных аргументов. Всегда передавайте их как именованные аргументы, то есть не полагайтесь на порядок объявления аргументов.523524> **`usage` (по умолчанию: `"%prog [options]"`)**525>526> Краткое описание использования (usage), которое выводится при неверном запуске программы или при запросе справки. Когда527>528> `optparse`529>530> выводит строку usage, он заменяет531>532> `%prog`533>534> на535>536> `os.path.basename(sys.argv[0])`537>538> (или на539>540> `prog`541>542> , если был передан этот именованный аргумент). Чтобы отключить вывод сообщения usage, передайте специальное значение543>544> `optparse.SUPPRESS_USAGE`545>546> .547>548> **`option_list` (по умолчанию: `[]`)**549>550> Список объектов Option для заполнения анализатора. Опции из551>552> `option_list`553>554> добавляются после всех опций из555>556> `standard_option_list`557>558> (атрибут класса, который может быть установлен подклассами OptionParser), но перед любыми опциями версии или справки. Устарело; используйте559>560> `add_option()`561>562> после создания анализатора.563>564> **`option_class` (по умолчанию: optparse.Option)**565>566> Класс, используемый при добавлении опций в анализатор с помощью567>568> `add_option()`569>570> .571>572> **`version` (по умолчанию: `None`)**573>574> Строка версии, которая выводится, когда пользователь указывает опцию версии. Если передать истинное значение для575>576> `version`577>578> ,579>580> `optparse`581>582> автоматически добавляет опцию версии с единственной строкой опции583>584> `"--version"`585>586> . Подстрока587>588> `"%prog"`589>590> раскрывается так же, как и для591>592> `usage`593>594> .595>596> **`conflict_handler` (по умолчанию: `"error"`)**597>598> Определяет поведение при добавлении опций с конфликтующими строками опций; см. раздел599>600> [*Конфликты между опциями*](https://python-all.ru/3.0/library/optparse.html#optparse-conflicts-between-options)601>602> .603>604> **`description` (по умолчанию: `None`)**605>606> Абзац текста с кратким обзором программы.607>608> `optparse`609>610> переформатирует этот абзац по ширине текущего терминала и выводит его при запросе справки (после611>612> `usage`613>614> , но до списка опций).615>616> **`formatter` (по умолчанию: новый IndentedHelpFormatter)**617>618> Экземпляр optparse.HelpFormatter, который будет использоваться для вывода текста справки.619>620> `optparse`621>622> предоставляет два конкретных класса для этой цели: IndentedHelpFormatter и TitledHelpFormatter.623>624> **`add_help_option` (по умолчанию: `True`)**625>626> Если true,627>628> `optparse`629>630> добавит в анализатор опцию справки (со строками опций631>632> `"-h"`633>634> и635>636> `"--help"`637>638> ).639>640> **`prog`**641>642> Строка, используемая при раскрытии643>644> `"%prog"`645>646> в647>648> `usage`649>650> и651>652> `version`653>654> вместо655>656> `os.path.basename(sys.argv[0])`657>658> .659660### Заполнение парсера661662Существует несколько способов заполнить анализатор опциями. Предпочтительный способ – использование `OptionParser.add_option()`, как показано в разделе [*Учебное пособие*](https://python-all.ru/3.0/library/optparse.html#optparse-tutorial). `add_option()` можно вызвать одним из двух способов:663664- передать ему экземпляр Option (возвращаемый функцией `make_option()`)665- передать любую комбинацию позиционных и именованных аргументов, которые допустимы для `make_option()` (т.е. для конструктора Option), и он создаст экземпляр Option автоматически666667Другой способ – передать список предварительно созданных экземпляров Option конструктору OptionParser, например:668669```python670option_list = [671    make_option("-f", "--filename",672                action="store", type="string", dest="filename"),673    make_option("-q", "--quiet",674                action="store_false", dest="verbose"),675    ]676parser = OptionParser(option_list=option_list)677```678679(`make_option()` – это фабричная функция для создания экземпляров Option; в настоящее время это псевдоним конструктора Option. Будущая версия `optparse` может разделить Option на несколько классов, и `make_option()` будет выбирать правильный класс для создания. Не создавайте экземпляры Option напрямую.)680681### Определение опций682683Каждый экземпляр Option представляет собой набор синонимичных строк опций командной строки, например *-f* и *--file*. Можно указать любое количество коротких или длинных строк опций, но необходимо указать хотя бы одну общую строку опции.684685Канонический способ создания экземпляра Option – с помощью метода `add_option()` класса `OptionParser`:686687```python688parser.add_option(opt_str[, ...], attr=value, ...)689```690691Для определения опции только с короткой строкой опции:692693```python694parser.add_option("-f", attr=value, ...)695```696697А для определения опции только с длинной строкой опции:698699```python700parser.add_option("--foo", attr=value, ...)701```702703Именованные аргументы определяют атрибуты нового объекта Option. Самый важный атрибут опции – `action`, и он во многом определяет, какие другие атрибуты являются уместными или обязательными. Если передать неуместные атрибуты опции или не указать обязательные, `optparse` выбрасывает исключение `OptionError` с объяснением ошибки.704705Атрибут *action* опции определяет, что `optparse` делает при встрече этой опции в командной строке. Стандартные действия опций, жёстко закодированные в `optparse`:706707**`store`**708709сохранить аргумент опции (по умолчанию)710711**`store_const`**712713сохранить константное значение714715**`store_true`**716717сохраняет истинное значение718719**`store_false`**720721сохраняет ложное значение722723**`append`**724725добавить аргумент этой опции в список726727**`append_const`**728729добавить константное значение в список730731**`count`**732733увеличить счётчик на единицу734735**`колбэк`**736737вызвать указанную функцию738739**[`help`](https://python-all.ru/3.0/library/functions.html#help)**740741вывести сообщение об использовании, включающее все опции и документацию к ним742743(Если не задано действие, по умолчанию используется `store`. Для этого действия также можно задать атрибуты опции [`type`](https://python-all.ru/3.0/library/functions.html#type) и `dest`; см. ниже.)744745Как видно, большинство действий сводится к сохранению или обновлению значения где-либо. `optparse` всегда создаёт для этого специальный объект, который традиционно называется `options` (на самом деле это экземпляр `optparse.Values`). Аргументы опций (и другие значения) сохраняются как атрибуты этого объекта в соответствии с атрибутом опции `dest` (назначение).746747Например, при вызове748749```python750parser.parse_args()751```752753одно из первых действий `optparse` – создать объект `options`:754755```python756options = Values()757```758759Если одна из опций в этом анализаторе определена с помощью760761```python762parser.add_option("-f", "--file", action="store", type="string", dest="filename")763```764765и разбираемая командная строка включает любую из следующих:766767```python768-ffoo769-f foo770--file=foo771--file foo772```773774затем `optparse`, увидев эту опцию, выполнит эквивалент775776```python777options.filename = "foo"778```779780Атрибуты опции [`type`](https://python-all.ru/3.0/library/functions.html#type) и `dest` почти так же важны, как `action`, но `action` – единственный, который имеет смысл для *всех* опций.781782### Стандартные действия опций783784Различные действия опций имеют несколько разные требования и эффекты. Большинство действий имеют несколько соответствующих атрибутов, которые можно указать, чтобы направить поведение `optparse`; некоторые имеют обязательные атрибуты, которые необходимо указать для любой опции, использующей это действие.785786- `store` \[значимые: [`type`](https://python-all.ru/3.0/library/functions.html#type), `dest`, `nargs`, `choices`\]787788  За опцией должен следовать аргумент, который преобразуется в значение согласно [`type`](https://python-all.ru/3.0/library/functions.html#type) и сохраняется в `dest`. Если `nargs` \> 1, из командной строки будет извлечено несколько аргументов; все они будут преобразованы согласно [`type`](https://python-all.ru/3.0/library/functions.html#type) и сохранены в `dest` в виде кортежа. См. раздел «Типы опций» ниже.789790  Если указан `choices` (список или кортеж строк), по умолчанию используется тип `choice`.791792  Если [`type`](https://python-all.ru/3.0/library/functions.html#type) не указан, по умолчанию используется `string`.793794  Если `dest` не указан, `optparse` выводит назначение из первой длинной строки опции (например, `"--foo-bar"` подразумевает `foo_bar`). Если длинных строк опции нет, `optparse` выводит назначение из первой короткой строки опции (например, `"-f"` подразумевает `f`).795796  Пример:797798  ```python799  parser.add_option("-f")800  parser.add_option("-p", type="float", nargs=3, dest="point")801  ```802803  В процессе разбора командной строки804805  ```python806  -f foo.txt -p 1 -3.5 4 -fbar.txt807  ```808809  `optparse` установит810811  ```python812  options.f = "foo.txt"813  options.point = (1.0, -3.5, 4.0)814  options.f = "bar.txt"815  ```816- `store_const` \[обязательно: `const`; значимые: `dest`\]817818  Значение `const` сохраняется в `dest`.819820  Пример:821822  ```python823  parser.add_option("-q", "--quiet",824                    action="store_const", const=0, dest="verbose")825  parser.add_option("-v", "--verbose",826                    action="store_const", const=1, dest="verbose")827  parser.add_option("--noisy",828                    action="store_const", const=2, dest="verbose")829  ```830831  Если встречается `"--noisy"`, `optparse` установит832833  ```python834  options.verbose = 2835  ```836- `store_true` \[значимые: `dest`\]837838  Частный случай `store_const`, который сохраняет истинное значение в `dest`.839- `store_false` \[значимые: `dest`\]840841  Как и `store_true`, но сохраняет ложное значение.842843  Пример:844845  ```python846  parser.add_option("--clobber", action="store_true", dest="clobber")847  parser.add_option("--no-clobber", action="store_false", dest="clobber")848  ```849- `append` \[значимые: [`type`](https://python-all.ru/3.0/library/functions.html#type), `dest`, `nargs`, `choices`\]850851  За опцией должен следовать аргумент, который добавляется в список в `dest`. Если для `dest` не задано значение по умолчанию, при первом обнаружении этой опции в командной строке `optparse` автоматически создаёт пустой список. Если `nargs` \> 1, извлекается несколько аргументов, и в `dest` добавляется кортеж длины `nargs`.852853  Значения по умолчанию для [`type`](https://python-all.ru/3.0/library/functions.html#type) и `dest` такие же, как для действия `store`.854855  Пример:856857  ```python858  parser.add_option("-t", "--tracks", action="append", type="int")859  ```860861  Если в командной строке встречается `"-t3"`, `optparse` делает то же самое, что:862863  ```python864  options.tracks = []865  options.tracks.append(int("3"))866  ```867868  Если чуть позже встречается `"--tracks=4"`, он делает:869870  ```python871  options.tracks.append(int("4"))872  ```873- `append_const` \[обязательно: `const`; значимые: `dest`\]874875  Как и `store_const`, но значение `const` добавляется в `dest`; как и в `append`, `dest` по умолчанию равен `None`, и при первом обнаружении опции автоматически создаётся пустой список.876- `count` \[значимые: `dest`\]877878  Увеличивает целое число, сохранённое в `dest`. Если значение по умолчанию не задано, `dest` устанавливается в ноль перед первым увеличением.879880  Пример:881882  ```python883  parser.add_option("-v", action="count", dest="verbosity")884  ```885886  При первом обнаружении `"-v"` в командной строке `optparse` делает то же самое, что:887888  ```python889  options.verbosity = 0890  options.verbosity += 1891  ```892893  Каждое последующее появление `"-v"` приводит к894895  ```python896  options.verbosity += 1897  ```898- `колбэк` \[обязательно: `колбэк`; связанные: [`type`](https://python-all.ru/3.0/library/functions.html#type), `nargs`, `callback_args`, `callback_kwargs`\]899900  Вызывает функцию, заданную `колбэк`, которая вызывается как901902  ```python903  func(option, opt_str, value, parser, *args, **kwargs)904  ```905906  Смотрите раздел [*Колбэки опций*](https://python-all.ru/3.0/library/optparse.html#optparse-option-callbacks) для подробностей.907- [`справка`](https://python-all.ru/3.0/library/functions.html#help)908909  Печатает полное сообщение справки для всех опций текущего анализатора опций. Сообщение справки формируется из строки `usage`, переданной конструктору OptionParser, и строки [`справка`](https://python-all.ru/3.0/library/functions.html#help), переданной каждой опции.910911  Если для опции не указана строка [`справка`](https://python-all.ru/3.0/library/functions.html#help), она всё равно будет показана в сообщении справки. Чтобы полностью исключить опцию, используйте специальное значение `optparse.SUPPRESS_HELP`.912913  `optparse` автоматически добавляет опцию [`справка`](https://python-all.ru/3.0/library/functions.html#help) во все объекты OptionParser, поэтому обычно нет необходимости создавать её вручную.914915  Пример:916917  ```python918  from optparse import OptionParser, SUPPRESS_HELP919920  parser = OptionParser()921  parser.add_option("-h", "--help", action="help"),922  parser.add_option("-v", action="store_true", dest="verbose",923                    help="Be moderately verbose")924  parser.add_option("--file", dest="filename",925                    help="Input file to read data from"),926  parser.add_option("--secret", help=SUPPRESS_HELP)927  ```928929  Если `optparse` встречает в командной строке `"-h"` или `"--help"`, он выводит примерно такое сообщение справки в stdout (при условии, что `sys.argv[0]` равен `"foo.py"`):930931  ```python932  usage: foo.py [options]933934  options:935    -h, --help        Show this help message and exit936    -v                Be moderately verbose937    --file=FILENAME   Input file to read data from938  ```939940  После вывода сообщения справки `optparse` завершает процесс с помощью `sys.exit(0)`.941- `версия`942943  Печатает номер версии, переданный OptionParser, в stdout и завершает работу. Номер версии форматируется и печатается методом `print_version()` класса OptionParser. Обычно имеет смысл только если аргумент `version` передан конструктору OptionParser. Как и с опциями [`справка`](https://python-all.ru/3.0/library/functions.html#help), вы редко будете создавать опции `версия`, поскольку `optparse` автоматически добавляет их при необходимости.944945### Атрибуты опций946947Следующие атрибуты опций могут быть переданы как именованные аргументы в `parser.add_option()`. Если передать атрибут, не соответствующий данной опции, или не передать обязательный атрибут опции, `optparse` возбуждает `OptionError`.948949- `действие` (по умолчанию: `"store"`)950951  Определяет поведение `optparse` при обнаружении этой опции в командной строке; доступные варианты описаны выше.952- [`тип`](https://python-all.ru/3.0/library/functions.html#type) (по умолчанию: `"string"`)953954  Тип аргумента, ожидаемый этой опцией (например, `"string"` или `"int"`); доступные типы опций описаны ниже.955- `назначение` (по умолчанию: выводится из строк опции)956957  Если действие опции подразумевает запись или изменение какого-либо значения, этот атрибут указывает `optparse`, куда его записать: `назначение` задаёт атрибут объекта `options`, который `optparse` создаёт при разборе командной строки.958- `default` (устарело)959960  Значение, используемое для назначения этой опции, если опция не обнаружена в командной строке. Устарело; вместо этого используйте `parser.set_defaults()`.961- `nargs` (по умолчанию: 1)962963  Сколько аргументов типа [`тип`](https://python-all.ru/3.0/library/functions.html#type) должно быть обработано при обнаружении этой опции. Если \> 1, `optparse` сохранит кортеж значений в `назначение`.964- `константа`965966  Для действий, сохраняющих постоянное значение, – само это постоянное значение.967- `варианты_выбора`968969  Для опций типа `"choice"` – список строк, из которых пользователь может выбирать.970- `колбэк`971972  Для опций с действием `"колбэк"` – вызываемый объект, который вызывается при обнаружении этой опции. Подробнее об аргументах, передаваемых в `callable`, см. раздел [*Колбэки опций*](https://python-all.ru/3.0/library/optparse.html#optparse-option-callbacks).973- `callback_args`, `callback_kwargs`974975  Дополнительные позиционные и именованные аргументы для передачи в `колбэк` после четырёх стандартных аргументов колбэка.976- [`справка`](https://python-all.ru/3.0/library/functions.html#help)977978  Текст справки для этой опции, выводимый при перечислении всех доступных опций после того, как пользователь укажет опцию [`справка`](https://python-all.ru/3.0/library/functions.html#help) (например, `"--help"`). Если текст справки не указан, опция будет выведена без текста. Чтобы скрыть эту опцию, используйте специальное значение `SUPPRESS_HELP`.979- `метапеременная` (по умолчанию: выводится из строк опции)980981  Замена для аргумента(ов) опции, используемая при выводе текста справки. Пример см. в разделе [*Учебник*](https://python-all.ru/3.0/library/optparse.html#optparse-tutorial).982983### Стандартные типы опций984985`optparse` имеет пять встроенных типов опций: `string`, `int`, `choice`, `float` и `complex`. Если вам нужно добавить новые типы опций, обратитесь к разделу [*Расширение optparse*](https://python-all.ru/3.0/library/optparse.html#optparse-extending-optparse).986987Аргументы строковых опций никак не проверяются и не преобразуются: текст из командной строки сохраняется в целевом атрибуте (или передаётся колбэку) как есть.988989Целочисленные аргументы (тип `int`) разбираются следующим образом:990991- если число начинается с `0x`, оно разбирается как шестнадцатеричное число992- если число начинается с `0`, оно разбирается как восьмеричное993- если число начинается с `0b`, оно разбирается как двоичное число994- в противном случае число разбирается как десятичное995996Преобразование выполняется вызовом `int()` с соответствующим основанием (2, 8, 10 или 16). Если это не удаётся, `optparse` также завершится ошибкой, но с более информативным сообщением.997998Аргументы опций `float` и `complex` преобразуются напрямую с помощью `float()` и `complex()`, с аналогичной обработкой ошибок.9991000Опции `choice` – это подтип опций `string`. Атрибут опции `choices` (последовательность строк) задаёт набор допустимых аргументов опции. `optparse.check_choice()` сравнивает переданные пользователем аргументы опции с этим основным списком и возбуждает `OptionValueError`, если указана недопустимая строка.10011002### Разбор аргументов10031004Весь смысл создания и настройки OptionParser – вызвать его метод `parse_args()`:10051006```python1007(options, args) = parser.parse_args(args=None, values=None)1008```10091010где входные параметры:10111012**`args`**10131014список аргументов для обработки (по умолчанию:10151016`sys.argv[1:]`10171018)10191020**`values`**10211022объект для хранения аргументов опций (по умолчанию: новый экземпляр optparse.Values)10231024а возвращаемые значения –10251026**`options`**10271028тот же объект, который был передан как10291030`options`10311032, или экземпляр optparse.Values, созданный10331034`optparse`10351036**`args`**10371038оставшиеся позиционные аргументы после обработки всех опций10391040Наиболее распространённый способ – не указывать ни один из именованных аргументов. Если указать `options`, он будет изменён многократными вызовами `setattr()` (примерно по одному на каждый аргумент опции, сохранённый в назначении опции) и возвращён `parse_args()`.10411042Если `parse_args()` встречает какие-либо ошибки в списке аргументов, он вызывает метод `error()` класса OptionParser с соответствующим сообщением об ошибке для конечного пользователя. Это в конечном итоге приводит к завершению процесса с кодом выхода 2 (традиционный код выхода Unix для ошибок командной строки).10431044### Запросы и изменение вашего парсера опций10451046Поведение анализатора опций по умолчанию можно немного настроить, а также можно исследовать анализатор опций и посмотреть, что в нём есть. OptionParser предоставляет несколько методов, которые помогут:10471048**`disable_interspersed_args()`**10491050Устанавливает режим разбора, при котором разбор останавливается на первом не-опционном аргументе. Используйте это, если у вас есть обработчик команд, который запускает другую команду, имеющую собственные опции, и вы хотите быть уверены, что эти опции не будут перепутаны. Например, каждая команда может иметь свой набор опций.10511052**`enable_interspersed_args()`**10531054Устанавливает режим разбора, при котором разбор не останавливается на первом не-опционном аргументе, позволяя перемешивать флаги с аргументами команды. Например,10551056`"-s arg1 --long arg2"`10571058вернёт10591060`["arg1", "arg2"]`10611062в качестве аргументов команды, а10631064`-s, --long`10651066– как опции. Это поведение по умолчанию.10671068**`get_option(opt_str)`**10691070Возвращает экземпляр Option с опционной строкой10711072`opt_str`10731074или10751076`None`10771078, если ни одна опция не имеет такой опционной строки.10791080**`has_option(opt_str)`**10811082Возвращает true, если OptionParser имеет опцию с опционной строкой10831084`opt_str`10851086(например,10871088`"-q"`10891090или10911092`"--verbose"`10931094).10951096**`remove_option(opt_str)`**10971098Если10991100`OptionParser`11011102содержит опцию, соответствующую11031104`opt_str`11051106, эта опция удаляется. Если эта опция предоставляла какие-либо другие опционные строки, все эти опционные строки становятся недействительными. Если11071108`opt_str`11091110не встречается ни в одной опции, принадлежащей этому11111112`OptionParser`11131114, возбуждается11151116[`ValueError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.ValueError)11171118.11191120### Конфликты между опциями11211122Если быть невнимательным, легко определить опции с конфликтующими строками опций:11231124```python1125parser.add_option("-n", "--dry-run", ...)1126[...]1127parser.add_option("-n", "--noisy", ...)1128```11291130(Это особенно актуально, если определён собственный подкласс OptionParser с некоторыми стандартными опциями.)11311132Каждый раз при добавлении опции `optparse` проверяет конфликты с существующими опциями. Если они находятся, вызывается текущий механизм разрешения конфликтов. Можно задать механизм разрешения конфликтов либо в конструкторе:11331134```python1135parser = OptionParser(..., conflict_handler=handler)1136```11371138или отдельным вызовом:11391140```python1141parser.set_conflict_handler(handler)1142```11431144Доступные обработчики конфликтов:11451146> **`error` (по умолчанию)**1147>1148> предполагать, что конфликты опций являются ошибкой программирования, и возбуждать1149>1150> `OptionConflictError`1151>1152> **`resolve`**1153>1154> разрешать конфликты опций интеллектуально (см. ниже)11551156В качестве примера давайте определим `OptionParser`, который разрешает конфликты интеллектуально, и добавим к нему конфликтующие опции:11571158```python1159parser = OptionParser(conflict_handler="resolve")1160parser.add_option("-n", "--dry-run", ..., help="do no harm")1161parser.add_option("-n", "--noisy", ..., help="be noisy")1162```11631164На этом этапе `optparse` обнаруживает, что ранее добавленная опция уже использует опционную строку `"-n"`. Поскольку `conflict_handler` равен `"resolve"`, он разрешает ситуацию, удаляя `"-n"` из списка опционных строк более ранней опции. Теперь `"--dry-run"` – единственный способ для пользователя активировать эту опцию. Если пользователь запросит справку, сообщение справки отразит это:11651166```python1167options:1168  --dry-run     do no harm1169  [...]1170  -n, --noisy   be noisy1171```11721173Можно сокращать строки опций для ранее добавленной опции, пока их не останется, и у пользователя не будет возможности вызвать эту опцию из командной строки. В этом случае `optparse` полностью удаляет эту опцию, так что она не появляется в тексте справки или где-либо ещё. Продолжая с нашим существующим OptionParser:11741175```python1176parser.add_option("--dry-run", ..., help="new dry-run option")1177```11781179На этом этапе исходная опция *-n/--dry-run* больше недоступна, поэтому `optparse` удаляет её, оставляя такой текст справки:11801181```python1182options:1183  [...]1184  -n, --noisy   be noisy1185  --dry-run     new dry-run option1186```11871188### Очистка11891190Экземпляры OptionParser имеют несколько циклических ссылок. Это не должно быть проблемой для сборщика мусора Python, но вы можете захотеть разорвать циклические ссылки явно, вызвав `destroy()` на вашем OptionParser, когда закончите с ним работать. Это особенно полезно в долго работающих приложениях, где большие графы объектов доступны из вашего OptionParser.11911192### Другие методы11931194OptionParser поддерживает несколько других открытых методов:11951196- `set_usage(usage)`11971198  Устанавливает строку использования в соответствии с правилами, описанными выше для `usage` именованного аргумента конструктора. Передача `None` устанавливает строку использования по умолчанию; используйте `SUPPRESS_USAGE`, чтобы подавить сообщение об использовании.1199- `enable_interspersed_args()`, `disable_interspersed_args()`12001201  Enable/disable positional arguments interspersed with options, similar to GNU getopt (enabled by default). For example, if `"-a"` and `"-b"` are both simple options that take no arguments, `optparse` normally accepts this syntax:12021203  ```python1204  prog -a arg1 -b arg21205  ```12061207  и обрабатывает его как эквивалент12081209  ```python1210  prog -a -b arg1 arg21211  ```12121213  Чтобы отключить эту возможность, вызовите `disable_interspersed_args()`. Это восстанавливает традиционный синтаксис Unix, где разбор опций останавливается на первом не-опционном аргументе.1214- `set_defaults(dest=value, ...)`12151216  Устанавливает значения по умолчанию для нескольких назначений опций одновременно. Использование `set_defaults()` – предпочтительный способ задания значений по умолчанию для опций, поскольку несколько опций могут совместно использовать одно назначение. Например, если несколько опций «mode» устанавливают одно и то же назначение, любая из них может задать значение по умолчанию, и побеждает последняя:12171218  ```python1219  parser.add_option("--advanced", action="store_const",1220                    dest="mode", const="advanced",1221                    default="novice")    # переопределено ниже1222  parser.add_option("--novice", action="store_const",1223                    dest="mode", const="novice",1224                    default="advanced")  # переопределяет вышеуказанную настройку1225  ```12261227  Чтобы избежать этой путаницы, используйте `set_defaults()`:12281229  ```python1230  parser.set_defaults(mode="advanced")1231  parser.add_option("--advanced", action="store_const",1232                    dest="mode", const="advanced")1233  parser.add_option("--novice", action="store_const",1234                    dest="mode", const="novice")1235  ```12361237## Колбэки опций12381239Когда встроенных действий и типов `optparse` недостаточно для ваших нужд, у вас есть два варианта: расширить `optparse` или определить опцию с колбэком. Расширение `optparse` более универсально, но избыточно для многих простых случаев. Часто достаточно простого колбэка.12401241Определение опции-колбэка состоит из двух шагов:12421243- определите саму опцию с помощью действия `колбэк`1244- написать колбэк – функцию (или метод), которая принимает как минимум четыре аргумента, как описано ниже12451246### Определение опции-колбэка12471248As always, the easiest way to define a callback option is by using the `parser.add_option()` method. Apart from `action`, the only option attribute you must specify is `callback`, the function to call:12491250```python1251parser.add_option("-c", action="callback", callback=my_callback)1252```12531254`колбэк` – это функция (или другой вызываемый объект), поэтому вы должны уже определить `my_callback()` до создания этой опции с колбэком. В этом простом случае `optparse` даже не знает, принимает ли [*-c*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-c) какие-то аргументы, что обычно означает, что опция не принимает аргументов – достаточно лишь присутствия [*-c*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-c) в командной строке. Однако в некоторых обстоятельствах колбэк может потреблять произвольное число аргументов командной строки. Вот здесь написание колбэков становится сложным; это рассматривается далее в этом разделе.12551256`optparse` всегда передаёт вашему колбэку четыре определённых аргумента и передаёт дополнительные, только если они заданы через `callback_args` и `callback_kwargs`. Таким образом, минимальная сигнатура функции колбэка:12571258```python1259def my_callback(option, opt, value, parser):1260```12611262Четыре аргумента колбэка описаны ниже.12631264Есть ещё несколько атрибутов опции, которые можно указать при определении опции-колбэка:12651266**[`type`](https://python-all.ru/3.0/library/functions.html#type)**12671268имеет обычное значение: как и для действий12691270`store`12711272или12731274`append`12751276, он предписывает12771278`optparse`12791280потребить один аргумент и преобразовать его в12811282[`type`](https://python-all.ru/3.0/library/functions.html#type)12831284. Однако, вместо сохранения преобразованного значения где-либо,12851286`optparse`12871288передаёт его вашей функции колбэка.12891290**`nargs`**12911292также имеет обычное значение: если указано и \> 1,12931294`optparse`12951296потребит12971298`nargs`12991300аргументов, каждый из которых должен быть преобразуем в13011302[`type`](https://python-all.ru/3.0/library/functions.html#type)13031304. Затем он передаёт кортеж преобразованных значений вашему колбэку.13051306**`callback_args`**13071308кортеж дополнительных позиционных аргументов, передаваемых колбэку13091310**`callback_kwargs`**13111312словарь дополнительных именованных аргументов, передаваемых колбэку13131314### Как вызываются колбэки13151316Все колбэки вызываются следующим образом:13171318```python1319func(option, opt_str, value, parser, *args, **kwargs)1320```13211322где13231324**`option`**13251326это экземпляр Option, который вызывает колбэк13271328**`opt_str`**13291330это строка опции, которая видна в командной строке и вызывает колбэк. (Если использовалась сокращённая длинная опция,13311332`opt_str`13331334будет полной, канонической строкой опции – например, если пользователь вводит13351336`"--foo"`13371338в командной строке как сокращение для13391340`"--foobar"`13411342, то13431344`opt_str`13451346будет13471348`"--foobar"`13491350.)13511352**`value`**13531354это аргумент этой опции, видимый в командной строке.13551356`optparse`13571358будет ожидать аргумент, только если задан13591360[`type`](https://python-all.ru/3.0/library/functions.html#type)13611362; тип13631364`value`13651366будет соответствовать типу, указанному в опции. Если13671368[`type`](https://python-all.ru/3.0/library/functions.html#type)13691370для этой опции равен13711372`None`13731374(аргумент не ожидается), то13751376`value`13771378будет13791380`None`13811382. Если13831384`nargs`13851386\> 1,13871388`value`13891390будет кортежем значений соответствующего типа.13911392**`parser`**13931394это экземпляр OptionParser, управляющий всем процессом; он полезен в основном тем, что через его атрибуты можно получить доступ к некоторым другим интересным данным:13951396**`parser.largs`**13971398текущий список оставшихся аргументов, то есть аргументов, которые были потреблены, но не являются ни опциями, ни аргументами опций. Можно свободно изменять13991400`parser.largs`14011402, например, добавляя в него новые аргументы. (Этот список станет14031404`args`14051406, вторым возвращаемым значением14071408`parse_args()`14091410.)14111412**`parser.rargs`**14131414текущий список оставшихся аргументов, то есть после удаления14151416`opt_str`14171418и14191420`value`14211422(если применимо), и только следующие за ними аргументы остаются. Можно свободно изменять14231424`parser.rargs`14251426, например, потребляя больше аргументов.14271428**`parser.values`**14291430объект, в котором по умолчанию хранятся значения опций (экземпляр optparse.OptionValues). Это позволяет колбэкам использовать тот же механизм хранения значений опций, что и остальная часть14311432`optparse`14331434; не нужно возиться с глобальными переменными или замыканиями. Также можно получать или изменять значения любых опций, уже встреченных в командной строке.14351436**`args`**14371438это кортеж произвольных позиционных аргументов, переданных через атрибут опции14391440`callback_args`14411442.14431444**`kwargs`**14451446это словарь произвольных именованных аргументов, переданных через14471448`callback_kwargs`14491450.14511452### Возбуждение ошибок в колбэке14531454Функция колбэка должна возбуждать `OptionValueError` при любых проблемах с опцией или её аргументами. `optparse` перехватывает это исключение и завершает программу, выводя в stderr переданное сообщение об ошибке. Сообщение должно быть ясным, кратким, точным и содержать ссылку на опцию, в которой проблема. Иначе пользователю будет трудно понять, что он сделал не так.14551456### Пример колбэка 1: тривиальный колбэк14571458Вот пример опции-колбэка, которая не принимает аргументов и просто записывает факт своего появления:14591460```python1461def record_foo_seen(option, opt_str, value, parser):1462    parser.values.saw_foo = True14631464parser.add_option("--foo", action="callback", callback=record_foo_seen)1465```14661467Разумеется, это можно сделать с помощью действия `store_true`.14681469### Пример колбэка 2: проверка порядка опций14701471Вот чуть более интересный пример: запоминать, что `"-a"` встретилась, но выдавать ошибку, если она стоит после `"-b"` в командной строке.14721473```python1474def check_order(option, opt_str, value, parser):1475    if parser.values.b:1476        raise OptionValueError("can't use -a after -b")1477    parser.values.a = 11478[...]1479parser.add_option("-a", action="callback", callback=check_order)1480parser.add_option("-b", action="store_true", dest="b")1481```14821483### Пример колбэка 3: проверка порядка параметров (обобщённый)14841485Если требуется повторно использовать этот колбэк для нескольких похожих опций (установить флаг, но выдать ошибку, если `"-b"` уже встречалась), потребуется доработка: сообщение об ошибке и устанавливаемый флаг необходимо обобщить.14861487```python1488def check_order(option, opt_str, value, parser):1489    if parser.values.b:1490        raise OptionValueError("can't use %s after -b" % opt_str)1491    setattr(parser.values, option.dest, 1)1492[...]1493parser.add_option("-a", action="callback", callback=check_order, dest='a')1494parser.add_option("-b", action="store_true", dest="b")1495parser.add_option("-c", action="callback", callback=check_order, dest='c')1496```14971498### Пример колбэка 4: проверка произвольного условия14991500Конечно, можно задать любое условие – вы не ограничены проверкой значений уже определённых параметров. Например, если есть параметры, которые не должны вызываться в полнолуние, достаточно сделать так:15011502```python1503def check_moon(option, opt_str, value, parser):1504    if is_moon_full():1505        raise OptionValueError("%s option invalid when moon is full"1506                               % opt_str)1507    setattr(parser.values, option.dest, 1)1508[...]1509parser.add_option("--foo",1510                  action="callback", callback=check_moon, dest="foo")1511```15121513(Определение `is_moon_full()` оставляется читателю в качестве упражнения.)15141515### Пример колбэка 5: фиксированное число аргументов15161517Ситуация становится немного интереснее, когда определяются колбэк-опции, принимающие фиксированное количество аргументов. Указание, что колбэк-опция принимает аргументы, аналогично определению опции `store` или `append`: если задать [`type`](https://python-all.ru/3.0/library/functions.html#type), то опция принимает один аргумент, который должен быть преобразуем к этому типу; если дополнительно задать `nargs`, то опция принимает `nargs` аргументов.15181519Вот пример, который просто эмулирует стандартное действие `store`:15201521```python1522def store_value(option, opt_str, value, parser):1523    setattr(parser.values, option.dest, value)1524[...]1525parser.add_option("--foo",1526                  action="callback", callback=store_value,1527                  type="int", nargs=3, dest="foo")1528```15291530Обратите внимание, что `optparse` самостоятельно заботится о потреблении 3 аргументов и преобразовании их в целые числа; всё, что нужно сделать – сохранить их. (Или что-то ещё; очевидно, для этого примера колбэк не нужен.)15311532### Пример колбэка 6: переменное число аргументов15331534Дело усложняется, когда требуется, чтобы опция принимала переменное число аргументов. В этом случае необходимо написать колбэк, поскольку `optparse` не предоставляет для этого встроенных возможностей. И придётся разобраться с некоторыми тонкостями традиционного разбора командной строки Unix, которые `optparse` обычно обрабатывает автоматически. В частности, колбэки должны реализовывать стандартные правила для аргументов `"--"` и `"-"`:15351536- как `"--"`, так и `"-"` могут быть аргументами параметра1537- голый `"--"` (если не является аргументом какого-либо параметра): остановить обработку командной строки и отбросить `"--"`1538- голый `"-"` (если не является аргументом какой-либо опции): остановить обработку командной строки, но сохранить `"-"` (добавить его в `parser.largs`)15391540Если требуется опция, принимающая переменное число аргументов, нужно учитывать несколько тонких и коварных моментов. Конкретная реализация будет зависеть от того, на какие компромиссы вы готовы пойти ради своего приложения (именно поэтому `optparse` не поддерживает такие вещи напрямую).15411542Тем не менее, вот пример попытки создать колбэк для параметра с переменным числом аргументов:15431544```python1545 def vararg_callback(option, opt_str, value, parser):1546     assert value is None1547     value = []15481549     def floatable(str):1550         try:1551             float(str)1552             return True1553         except ValueError:1554             return False15551556     for arg in parser.rargs:1557         # останавливаться на опциях вида --foo1558         if arg[:2] == "--" and len(arg) > 2:1559             break1560         # останавливаться на -a, но не на -3 или -3.01561         if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):1562             break1563         value.append(arg)15641565     del parser.rargs[:len(value)]1566     setattr(parser.values, option.dest, value)15671568[...]1569parser.add_option("-c", "--callback", dest="vararg_attr",1570                  action="callback", callback=vararg_callback)1571```15721573## Расширение `optparse`15741575Поскольку двумя основными управляющими факторами, определяющими, как `optparse` интерпретирует опции командной строки, являются действие и тип каждой опции, наиболее вероятное направление расширения – добавление новых действий и новых типов.15761577### Добавление новых типов15781579Чтобы добавить новые типы, нужно определить собственный подкласс класса Option из `optparse`. У этого класса есть несколько атрибутов, определяющих типы `optparse`: `TYPES` и `TYPE_CHECKER`.15801581`TYPES` – это кортеж имен типов; в своем подклассе просто определите новый кортеж `TYPES`, который расширяет стандартный.15821583`TYPE_CHECKER` – это словарь, сопоставляющий имена типов с функциями проверки типа. Функция проверки типа имеет следующую сигнатуру:15841585```python1586def check_mytype(option, opt, value)1587```15881589где `option` – это экземпляр `Option`, `opt` – строка опции (например, `"-f"`), а `value` – строка из командной строки, которую нужно проверить и преобразовать к нужному типу. `check_mytype()` должна возвращать объект гипотетического типа `mytype`. Значение, возвращаемое функцией проверки типа, в итоге оказывается в экземпляре OptionValues, возвращаемом `OptionParser.parse_args()`, или передается колбэку как параметр `value`.15901591Функция проверки типа должна возбуждать `OptionValueError` при возникновении каких-либо проблем. `OptionValueError` принимает один строковый аргумент, который передается как есть методу `OptionParser`.`error()`; тот, в свою очередь, добавляет имя программы и строку `"error:"`, выводит все в stderr и завершает процесс.15921593Вот глупый пример, демонстрирующий добавление типа опции `complex` для разбора комплексных чисел в стиле Python из командной строки. (Это еще более глупо, чем раньше, потому что `optparse` 1.3 добавил встроенную поддержку комплексных чисел, но не будем об этом.)15941595Сначала необходимые импорты:15961597```python1598from copy import copy1599from optparse import Option, OptionValueError1600```16011602Сначала нужно определить проверку типа, так как на нее есть ссылка позже (в атрибуте класса `TYPE_CHECKER` вашего подкласса Option):16031604```python1605def check_complex(option, opt, value):1606    try:1607        return complex(value)1608    except ValueError:1609        raise OptionValueError(1610            "option %s: invalid complex value: %r" % (opt, value))1611```16121613Наконец, подкласс Option:16141615```python1616class MyOption (Option):1617    TYPES = Option.TYPES + ("complex",)1618    TYPE_CHECKER = copy(Option.TYPE_CHECKER)1619    TYPE_CHECKER["complex"] = check_complex1620```16211622(Если бы мы не сделали `copy()` от `Option.TYPE_CHECKER`, мы бы изменили атрибут `TYPE_CHECKER` класса Option из `optparse`. Поскольку это Python, ничто не мешает так поступить, кроме хороших манер и здравого смысла.)16231624Вот и всё! Теперь можно написать скрипт, использующий новый тип опций так же, как и любой другой скрипт на основе `optparse`, за исключением того, что нужно указать OptionParser использовать MyOption вместо Option:16251626```python1627parser = OptionParser(option_class=MyOption)1628parser.add_option("-c", type="complex")1629```16301631В качестве альтернативы можно составить собственный список опций и передать его OptionParser; если не использовать `add_option()` указанным выше способом, не нужно сообщать OptionParser, какой класс опций использовать:16321633```python1634option_list = [MyOption("-c", action="store", type="complex", dest="c")]1635parser = OptionParser(option_list=option_list)1636```16371638### Добавление новых действий16391640Добавление новых действий немного сложнее, потому что нужно понимать, что у `optparse` есть несколько классификаций действий:16411642**«store»-действия**16431644действия, в результате которых16451646`optparse`16471648сохраняет значение в атрибут текущего экземпляра OptionValues; для таких опций требуется атрибут16491650`dest`16511652, передаваемый конструктору Option16531654**«typed»-действия**16551656действия, которые берут значение из командной строки и ожидают, что оно будет определенного типа; точнее, строка, которую можно преобразовать к определенному типу. Для таких опций требуется атрибут16571658[`type`](https://python-all.ru/3.0/library/functions.html#type)16591660конструктора Option.16611662Это пересекающиеся множества: некоторые стандартные действия «store»: `store`, `store_const`, `append` и `count`, а стандартные действия «typed»: `store`, `append` и `колбэк`.16631664При добавлении действия его нужно отнести к категории, включив как минимум в один из следующих атрибутов класса Option (все они являются списками строк):16651666**`ACTIONS`**16671668все действия должны быть перечислены в ACTIONS16691670**`STORE_ACTIONS`**16711672«store»-действия дополнительно перечислены здесь16731674**`TYPED_ACTIONS`**16751676«typed»-действия дополнительно перечислены здесь16771678**`ALWAYS_TYPED_ACTIONS`**16791680действия, которые всегда используют тип (т.е. их опции всегда принимают значение), дополнительно перечислены здесь. Единственный эффект этого заключается в том, что16811682`optparse`16831684назначает тип по умолчанию,16851686`string`16871688, опциям без явного типа, чье действие перечислено в16891690`ALWAYS_TYPED_ACTIONS`16911692.16931694Чтобы реализовать новое действие, необходимо переопределить метод Option `take_action()` и добавить ветвь, распознающую это действие.16951696Например, давайте добавим действие `extend`. Оно похоже на стандартное действие `append`, но вместо того, чтобы взять одно значение из командной строки и добавить его в существующий список, `extend` возьмет несколько значений в одной строке, разделенной запятыми, и расширит существующий список этими значениями. То есть, если `"--names"` – это опция `extend` типа `string`, то командная строка16971698```python1699--names=foo,bar --names blah --names ding,dong1700```17011702приведёт к списку17031704```python1705["foo", "bar", "blah", "ding", "dong"]1706```17071708Снова определим подкласс Option:17091710```python1711class MyOption (Option):17121713    ACTIONS = Option.ACTIONS + ("extend",)1714    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)1715    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)1716    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)17171718    def take_action(self, action, dest, opt, value, values, parser):1719        if action == "extend":1720            lvalue = value.split(",")1721            values.ensure_value(dest, []).extend(lvalue)1722        else:1723            Option.take_action(1724                self, action, dest, opt, value, values, parser)1725```17261727Что следует отметить:17281729- `extend` и ожидает значение в командной строке, и сохраняет его где-то, поэтому оно попадает и в `STORE_ACTIONS`, и в `TYPED_ACTIONS`1730- чтобы `optparse` назначал тип по умолчанию `string` для действий `extend`, мы также помещаем действие `extend` в `ALWAYS_TYPED_ACTIONS`1731- `MyOption.take_action()` реализует только это одно новое действие и передает управление обратно `Option.take_action()` для стандартных действий `optparse`1732- `values` – это экземпляр класса optparse\_parser.Values, который предоставляет очень полезный метод `ensure_value()`. `ensure_value()` – это, по сути, [`getattr()`](https://python-all.ru/3.0/library/functions.html#getattr) с предохранительным клапаном; он вызывается как17331734  ```python1735  values.ensure_value(attr, value)1736  ```17371738  Если атрибут `attr` объекта `values` не существует или равен None, то ensure\_value() сначала устанавливает его в `value`, а затем возвращает значение. Это очень удобно для таких действий, как `extend`, `append` и `count`, все они накапливают данные в переменной и ожидают, что эта переменная будет определенного типа (список для первых двух, целое число для последнего). Использование `ensure_value()` означает, что сценарии, использующие ваше действие, могут не беспокоиться о задании значения по умолчанию для соответствующих опций; они могут просто оставить значение по умолчанию None, и `ensure_value()` позаботится о правильной установке, когда это потребуется.1739