# `optparse` — Parser for command line options

Вихідний код: Lib/optparse.py

Застаріло починаючи з версії 3.2: The `optparse` module is soft deprecated and will not be developed further; development will continue with the `argparse` module.

`optparse` — це більш зручна, гнучка та потужна бібліотека для аналізу параметрів командного рядка, ніж старий модуль `getopt`. `optparse` використовує більш декларативний стиль аналізу командного рядка: ви створюєте екземпляр `OptionParser`, заповнюєте його параметрами та аналізуєте командний рядок. `optparse` дозволяє користувачам вказувати параметри у звичайному синтаксисі GNU/POSIX, а також створює для вас повідомлення про використання та довідку.

Ось приклад використання `optparse` у простому сценарії:

    from optparse import OptionParser
    ...
    parser = OptionParser()
    parser.add_option("-f", "--file", dest="filename",
                      help="write report to FILE", metavar="FILE")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose", default=True,
                      help="don't print status messages to stdout")

    (options, args) = parser.parse_args()

За допомогою цих кількох рядків коду користувачі вашого сценарію тепер можуть виконувати «звичайні дії» в командному рядку, наприклад:

    <yourscript> --file=outfile -q

As it parses the command line, `optparse` sets attributes of the `options` object returned by `parse_args()` based on user-supplied command-line values. When `parse_args()` returns from parsing this command line, `options.filename` will be `"outfile"` and `options.verbose` will be `False`. `optparse` supports both long and short options, allows short options to be merged together, and allows options to be associated with their arguments in a variety of ways. Thus, the following command lines are all equivalent to the above example:

    <yourscript> -f outfile --quiet
    <yourscript> --quiet --file outfile
    <yourscript> -q -foutfile
    <yourscript> -qfoutfile

Крім того, користувачі можуть запустити одну з таких команд:

    <yourscript> -h
    <yourscript> --help

і `optparse` виведе короткий опис параметрів вашого сценарію:

    Usage: <yourscript> [options]

    Options:
      -h, --help            show this help message and exit
      -f FILE, --file=FILE  write report to FILE
      -q, --quiet           don't print status messages to stdout

де значення yourscript визначається під час виконання (зазвичай із `sys.argv[0]`).

## Фон

`optparse` був спеціально розроблений, щоб заохочувати створення програм із простими звичайними інтерфейсами командного рядка. З цією метою він підтримує лише найпоширеніший синтаксис і семантику командного рядка, які зазвичай використовуються в Unix. Якщо ви не знайомі з цими умовними поняттями, прочитайте цей розділ, щоб ознайомитися з ними.

### Термінологія

аргумент

  рядок, введений у командному рядку та переданий оболонкою до `execl()` або `execv()`. У Python аргументи є елементами `sys.argv[1:]` (`sys.argv[0]` це ім’я програми, що виконується). Оболонки Unix також використовують термін «слово».

  Час від часу бажано замінити список аргументів іншим, ніж `sys.argv[1:]`, тому ви повинні читати «аргумент» як «елемент `sys.argv[1:]` або деяких інший список надається замість `sys.argv[1:]`».

варіант

  аргумент, який використовується для надання додаткової інформації для керівництва або налаштування виконання програми. Існує багато різних синтаксисів для параметрів; традиційний синтаксис Unix - це дефіс («-«), за яким йде одна літера, напр. `-x` або `-F`. Крім того, традиційний синтаксис Unix дозволяє об’єднати кілька параметрів в один аргумент, наприклад. `-x -F` еквівалентно `-xF`. У проекті GNU було введено `--`, за яким йшов ряд слів, розділених дефісом, напр. `--file` або `--dry-run`. Це єдині два синтаксиси параметрів, які надає `optparse`.

  Деякі інші синтаксиси параметрів, які бачив світ, включають:

  - дефіс, за яким слідує кілька літер, напр. `-pf` (це не те саме, що кілька параметрів, об’єднаних в один аргумент)

  - дефіс, за яким іде ціле слово, напр. `-файл` (технічно це еквівалент попереднього синтаксису, але вони зазвичай не зустрічаються в одній програмі)

  - знак плюс, після якого йде одна літера, або кілька літер, або слово, напр. `+f`, `+rgb`

  - косу риску, за якою йде літера, або кілька літер, або слово, напр. `/f`, `/file`

  Ці синтаксиси параметрів не підтримуються `optparse`, і вони ніколи не будуть. Це зроблено навмисно: перші три є нестандартними для будь-якого середовища, а останній має сенс, лише якщо ви націлені виключно на Windows або певні застарілі платформи (наприклад, VMS, MS-DOS).

аргумент опції

  аргумент, який слідує за опцією, тісно пов’язаний із цією опцією та споживається зі списку аргументів, коли ця опція є. З `optparse` аргументи опції можуть бути в окремому аргументі від їхньої опції:

      -f foo
      --file foo

  або включено в той самий аргумент:

      -ffoo
      --file=foo

  Як правило, певна опція приймає аргумент або ні. Багатьом людям потрібна функція «необов’язкових аргументів параметрів», тобто деякі параметри прийматимуть аргумент, якщо вони його бачать, і ні, якщо вони його не бачать. Це дещо суперечливо, оскільки це робить розбір неоднозначним: якщо `-a` приймає необов’язковий аргумент, а `-b` є іншим варіантом, як ми інтерпретуємо `-ab`? Через цю неоднозначність `optparse` не підтримує цю функцію.

позиційний аргумент

  щось, що залишилося в списку аргументів після аналізу параметрів, тобто після аналізу параметрів і їхніх аргументів і видалення зі списку аргументів.

необхідна опція

  параметр, який необхідно вказати в командному рядку; зауважте, що фраза «необхідна опція» є суперечливою англійською мовою. `optparse` не заважає вам реалізовувати необхідні параметри, але й не дуже допомагає в цьому.

Наприклад, розглянемо цей гіпотетичний командний рядок:

    prog -v --report report.txt foo bar

`-v` і `--report` є варіантами. Якщо припустити, що `--report` приймає один аргумент, `report.txt` є аргументом опції. `foo` і `bar` є позиційними аргументами.

### Для чого існують варіанти?

Параметри використовуються для надання додаткової інформації для налаштування або налаштування виконання програми. Якщо це було незрозуміло, параметри зазвичай необов’язкові. Програма повинна нормально працювати без будь-яких опцій. (Виберіть випадкову програму з наборів інструментів Unix або GNU. Чи може вона запускатися взагалі без будь-яких параметрів і мати сенс? Основними винятками є `find`, `tar` і `dd`– - усі вони є диваками-мутантами, яких справедливо критикували за нестандартний синтаксис і заплутані інтерфейси.)

Багато людей хочуть, щоб їхні програми мали «необхідні параметри». Подумай над цим. Якщо це потрібно, то це не обов’язково! Якщо є частина інформації, яка абсолютно необхідна вашій програмі для успішної роботи, це те, для чого потрібні позиційні аргументи.

Як приклад гарного дизайну інтерфейсу командного рядка розглянемо скромну утиліту `cp` для копіювання файлів. Немає особливого сенсу намагатися скопіювати файли, не вказавши місце призначення та принаймні одне джерело. Отже, `cp` не вдається, якщо ви запускаєте його без аргументів. Однак він має гнучкий, корисний синтаксис, який не потребує жодних опцій:

    cp SOURCE DEST
    cp SOURCE ... DEST-DIR

Тільки з цим можна зайти досить далеко. Більшість реалізацій `cp` надають безліч параметрів для точного налаштування способу копіювання файлів: ви можете зберегти режим і час модифікації, уникати переходу за символічними посиланнями, запитувати перед тим, як затирати існуючі файли, тощо. Але це не відволікає від основної місії `cp`, який скопіює або один файл до іншого, або декілька файлів до іншого каталогу.

### Для чого потрібні позиційні аргументи?

Позиційні аргументи призначені для тих фрагментів інформації, які вашій програмі абсолютно необхідні для роботи.

Хороший інтерфейс користувача повинен мати якомога менше абсолютних вимог. Якщо ваша програма потребує 17 окремих фрагментів інформації для успішної роботи, не має великого значення як ви отримуєте цю інформацію від користувача — більшість людей здадуться та підуть, перш ніж вони успішно запустять програму. Це стосується незалежно від того, чи є інтерфейс користувача командним рядком, файлом конфігурації чи графічним інтерфейсом користувача: якщо ви поставите стільки вимог до своїх користувачів, більшість із них просто здадуться.

Коротше кажучи, намагайтеся мінімізувати кількість інформації, яку користувачі абсолютно зобов’язані надавати — використовуйте розумні значення за замовчуванням, коли це можливо. Звичайно, ви також хочете зробити свої програми досить гнучкими. Для цього і потрібні варіанти. Знову ж таки, не має значення, чи це записи у конфігураційному файлі, віджети в діалоговому вікні «Параметри» графічного інтерфейсу користувача чи параметри командного рядка — чим більше параметрів ви застосовуєте, тим гнучкішою є ваша програма, і ускладнюється його реалізація. Занадто велика гнучкість також має недоліки, звичайно; занадто багато параметрів може перевантажити користувачів і зробити ваш код набагато складнішим для підтримки.

## Підручник

Хоча `optparse` досить гнучкий і потужний, він також простий у використанні в більшості випадків. Цей розділ охоплює шаблони коду, які є спільними для будь-якої програми на основі `optparse`.

По-перше, вам потрібно імпортувати клас OptionParser; потім на початку основної програми створіть екземпляр OptionParser:

    from optparse import OptionParser
    ...
    parser = OptionParser()

Потім можна приступати до визначення варіантів. Основний синтаксис:

    parser.add_option(opt_str, ...,
                      attr=value, ...)

Кожна опція має один або більше рядків опції, наприклад `-f` або `--file`, і кілька атрибутів опції, які повідомляють `optparse`, чого очікувати і що робити, коли він зустрічає цю опцію в командному рядку.

Як правило, кожен параметр матиме один короткий рядок параметра та один довгий рядок параметра, наприклад:

    parser.add_option("-f", "--file", ...)

Ви можете визначати скільки завгодно коротких рядків параметрів і скільки завгодно довгих рядків параметрів (включаючи нуль), за умови, що є принаймні один рядок параметрів.

Рядки параметрів, передані до `OptionParser.add_option()`, фактично є мітками для параметра, визначеного цим викликом. Для стислості ми будемо часто посилатися на зустріч параметра в командному рядку; насправді `optparse` зустрічає рядки параметрів і шукає параметри з них.

Коли всі ваші параметри визначено, дайте команду `optparse` проаналізувати командний рядок вашої програми:

    (options, args) = parser.parse_args()

(If you like, you can pass a custom argument list to `parse_args()`, but that’s rarely necessary: by default it uses `sys.argv[1:]`.)

`parse_args()` returns two values:

- `options`, об’єкт, що містить значення для всіх ваших параметрів — напр. якщо `--file` приймає один рядковий аргумент, `options.file` буде іменем файлу, наданим користувачем, або `None`, якщо користувач не вказав цей параметр

- `args`, список позиційних аргументів, що залишилися після аналізу параметрів

Цей розділ посібника охоплює лише чотири найважливіші атрибути параметрів: `action`, `type`, `dest` (призначення) і `help`. З них `action` є найбільш фундаментальним.

### Розуміння опціональних дій

Дії повідомляють `optparse`, що робити, коли він зустрічає опцію в командному рядку. Існує фіксований набір дій, жорстко закодований у `optparse`; додавання нових дій є розширеною темою, розглянутою в розділі Розширення optparse. Більшість дій говорять `optparse` зберігати значення в деякій змінній — наприклад, взяти рядок із командного рядка та зберегти його в атрибуті `options`.

Якщо ви не вкажете опцію дії, `optparse` за замовчуванням буде `store`.

### Акція магазину

Найпоширенішою дією опції є `store`, яка повідомляє `optparse` взяти наступний аргумент (або решту поточного аргументу), переконатися, що він має правильний тип, і зберегти його у вибраному призначення.

Наприклад:

    parser.add_option("-f", "--file",
                      action="store", type="string", dest="filename")

Тепер давайте створимо фальшивий командний рядок і попросимо `optparse` розібрати його:

    args = ["-f", "foo.txt"]
    (options, args) = parser.parse_args(args)

When `optparse` sees the option string `-f`, it consumes the next argument, `foo.txt`, and stores it in `options.filename`. So, after this call to `parse_args()`, `options.filename` is `"foo.txt"`.

Деякі інші типи опцій, які підтримує `optparse`, це `int` і `float`. Ось варіант, який очікує цілочисельний аргумент:

    parser.add_option("-n", type="int", dest="num")

Зауважте, що цей параметр не має довгого рядка параметрів, що цілком прийнятно. Крім того, немає явної дії, оскільки за замовчуванням є `store`.

Давайте розберемо ще один підроблений командний рядок. Цього разу ми зіткнемося з аргументом option прямо проти параметра: оскільки `-n42` (один аргумент) еквівалентний `-n 42` (два аргументи), код

    (options, args) = parser.parse_args(["-n42"])
    print(options.num)

надрукує `42`.

Якщо ви не вкажете тип, `optparse` припускає `рядок`. У поєднанні з тим фактом, що типовою дією є `store`, це означає, що наш перший приклад може бути набагато коротшим:

    parser.add_option("-f", "--file", dest="filename")

Якщо ви не вкажете призначення, `optparse` визначає розумне значення за замовчуванням із рядків параметрів: якщо перший довгий рядок параметрів – `--foo-bar`, тоді призначенням за замовчуванням є `foo_bar`. Якщо довгих рядків параметрів немає, `optparse` шукає перший короткий рядок параметрів: типовим призначенням для `-f` є `f`.

`optparse` також містить вбудований тип `complex`. Додавання типів описано в розділі Розширення optparse.

### Обробка логічних параметрів (прапорів).

Параметри прапорів — встановлюють для змінної значення true або false, коли відображається певний параметр — досить поширені. `optparse` підтримує їх за допомогою двох окремих дій, `store_true` і `store_false`. Наприклад, у вас може бути прапорець `verbose`, який вмикається за допомогою `-v` і вимикається `-q`:

    parser.add_option("-v", action="store_true", dest="verbose")
    parser.add_option("-q", action="store_false", dest="verbose")

Тут у нас є два різні варіанти з тим самим пунктом призначення, що цілком нормально. (Це лише означає, що ви повинні бути трохи обережними, встановлюючи значення за замовчуванням — див. нижче.)

Коли `optparse` зустрічає `-v` у командному рядку, він встановлює `options.verbose` на `True`; коли зустрічається `-q`, `options.verbose` встановлюється на `False`.

### Інші дії

Деякі інші дії, які підтримує `optparse`:

`"store_const"`

  store a constant value, pre-set via `Option.const`

`"додати"`

  додати аргумент цього параметра до списку

`"рахувати"`

  збільшити лічильник на одиницю

`"зворотний виклик"`

  викликати вказану функцію

Вони описані в розділі Довідковий посібник і розділі Опція зворотних викликів.

### Значення за замовчуванням

Усі наведені вище приклади включають встановлення деякої змінної («призначення»), коли відображаються певні параметри командного рядка. Що трапиться, якщо ці варіанти ніколи не побачать? Оскільки ми не вказали жодних значень за замовчуванням, для всіх встановлено значення `None`. Зазвичай це добре, але іноді потрібно більше контролю. `optparse` дозволяє вказати значення за умовчанням для кожного пункту призначення, яке призначається перед аналізом командного рядка.

Спочатку розглянемо багатослівний/тихий приклад. Якщо ми хочемо, щоб `optparse` встановив для `verbose` значення `True`, якщо не видно `-q`, ми можемо зробити це:

    parser.add_option("-v", action="store_true", dest="verbose", default=True)
    parser.add_option("-q", action="store_false", dest="verbose")

Оскільки значення за замовчуванням застосовуються до призначення, а не до будь-якого конкретного параметра, і ці два параметри мають одне призначення, це точно еквівалентно:

    parser.add_option("-v", action="store_true", dest="verbose")
    parser.add_option("-q", action="store_false", dest="verbose", default=True)

Розглянемо це:

    parser.add_option("-v", action="store_true", dest="verbose", default=False)
    parser.add_option("-q", action="store_false", dest="verbose", default=True)

Знову ж таки, значенням за замовчуванням для `verbose` буде `True`: останнє значення за замовчуванням, надане для будь-якого конкретного призначення, є тим, яке враховується.

A clearer way to specify default values is the `set_defaults()` method of OptionParser, which you can call at any time before calling `parse_args()`:

    parser.set_defaults(verbose=True)
    parser.add_option(...)
    (options, args) = parser.parse_args()

Як і раніше, зараховується останнє значення, указане для даного призначення опції. Для ясності спробуйте використовувати один або інший метод встановлення значень за замовчуванням, а не обидва.

### Створення довідки

Здатність `optparse` автоматично генерувати текст довідки та використання корисна для створення зручних інтерфейсів командного рядка. Все, що вам потрібно зробити, це вказати значення `help` для кожного параметра та, за бажанням, коротке повідомлення про використання для всієї програми. Ось OptionParser, заповнений зручними (задокументованими) параметрами:

    usage = "usage: %prog [options] arg1 arg2"
    parser = OptionParser(usage=usage)
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose", default=True,
                      help="make lots of noise [default]")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose",
                      help="be vewwy quiet (I'm hunting wabbits)")
    parser.add_option("-f", "--filename",
                      metavar="FILE", help="write output to FILE")
    parser.add_option("-m", "--mode",
                      default="intermediate",
                      help="interaction mode: novice, intermediate, "
                           "or expert [default: %default]")

Якщо `optparse` зустрічає `-h` або `--help` у командному рядку, або якщо ви просто викликаєте `parser.print_help()`, він виводить наступне у стандартний вивід :

    Usage: <yourscript> [options] arg1 arg2

    Options:
      -h, --help            show this help message and exit
      -v, --verbose         make lots of noise [default]
      -q, --quiet           be vewwy quiet (I'm hunting wabbits)
      -f FILE, --filename=FILE
                            write output to FILE
      -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                            expert [default: intermediate]

(Якщо вихід довідки ініціюється опцією довідки, `optparse` завершує роботу після друку тексту довідки.)

Тут багато чого робиться, щоб допомогти `optparse` створити найкраще довідкове повідомлення:

- сценарій визначає власне повідомлення про використання:

      usage = "usage: %prog [options] arg1 arg2"

  `optparse` розширює `%prog` у рядку використання до назви поточної програми, тобто `os.path.basename(sys.argv[0])`. Потім розгорнутий рядок друкується перед детальною довідкою параметрів.

  Якщо ви не вказали рядок використання, `optparse` використовує м’яке, але розумне значення за умовчанням: `"Використання: %prog [параметри]"`, що добре, якщо ваш сценарій не приймає жодних позиційних аргументів.

- кожен параметр визначає довідковий рядок і не турбується про перенесення рядків—`optparse` піклується про обтікання рядків і робить вихід довідки гарним.

- options that take a value indicate this fact in their automatically generated help message, e.g. for the «mode» option:

      -m MODE, --mode=MODE

  Here, «MODE» is called the meta-variable: it stands for the argument that the user is expected to supply to `-m`/`--mode`. By default, `optparse` converts the destination variable name to uppercase and uses that for the meta-variable. Sometimes, that’s not what you want—for example, the `--filename` option explicitly sets `metavar="FILE"`, resulting in this automatically generated option description:

      -f FILE, --filename=FILE

  Однак це важливо не тільки для економії місця: написаний вручну текст довідки використовує мета-змінну `FILE`, щоб зрозуміти користувачеві, що існує зв’язок між напівформальним синтаксисом `-f FILE` і неформальний семантичний опис «записати вихід у ФАЙЛ». Це простий, але ефективний спосіб зробити ваш текст довідки набагато зрозумілішим і кориснішим для кінцевих користувачів.

- параметри, які мають значення за замовчуванням, можуть містити `%default` у рядку довідки —`optparse` замінить його на `str()` значення параметра за замовчуванням. Якщо параметр не має значення за замовчуванням (або стандартним значенням є `None`), `%default` розширюється до `none`.

#### Параметри групування

Коли ви маєте справу з багатьма параметрами, зручно згрупувати ці параметри для кращого виведення довідки. `OptionParser` може містити кілька груп опцій, кожна з яких може містити кілька опцій.

Група опцій отримується за допомогою класу `OptionGroup`:

class optparse.OptionGroup(parser, title, description=None)

  де

  - parser — це екземпляр `OptionParser`, до якого буде вставлено групу

  - title — назва групи

  - description, необов’язковий, це довгий опис групи

`OptionGroup` успадковує `OptionContainer` (наприклад, `OptionParser`), тому метод `add_option()` можна використовувати для додавання опції до групи.

Після оголошення всіх опцій за допомогою методу `OptionParser` `add_option_group()` група додається до попередньо визначеного аналізатора.

Продовжуючи роботу з аналізатором, визначеним у попередньому розділі, додати `OptionGroup` до аналізатора легко:

    group = OptionGroup(parser, "Dangerous Options",
                        "Caution: use these options at your own risk.  "
                        "It is believed that some of them bite.")
    group.add_option("-g", action="store_true", help="Group option.")
    parser.add_option_group(group)

Це призведе до наступного результату довідки:

    Usage: <yourscript> [options] arg1 arg2

    Options:
      -h, --help            show this help message and exit
      -v, --verbose         make lots of noise [default]
      -q, --quiet           be vewwy quiet (I'm hunting wabbits)
      -f FILE, --filename=FILE
                            write output to FILE
      -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                            expert [default: intermediate]

      Dangerous Options:
        Caution: use these options at your own risk.  It is believed that some
        of them bite.

        -g                  Group option.

Трохи повніший приклад може включати використання кількох груп: все ще розширюючи попередній приклад:

    group = OptionGroup(parser, "Dangerous Options",
                        "Caution: use these options at your own risk.  "
                        "It is believed that some of them bite.")
    group.add_option("-g", action="store_true", help="Group option.")
    parser.add_option_group(group)

    group = OptionGroup(parser, "Debug Options")
    group.add_option("-d", "--debug", action="store_true",
                     help="Print debug information")
    group.add_option("-s", "--sql", action="store_true",
                     help="Print all SQL statements executed")
    group.add_option("-e", action="store_true", help="Print every action done")
    parser.add_option_group(group)

що призводить до наступного результату:

    Usage: <yourscript> [options] arg1 arg2

    Options:
      -h, --help            show this help message and exit
      -v, --verbose         make lots of noise [default]
      -q, --quiet           be vewwy quiet (I'm hunting wabbits)
      -f FILE, --filename=FILE
                            write output to FILE
      -m MODE, --mode=MODE  interaction mode: novice, intermediate, or expert
                            [default: intermediate]

      Dangerous Options:
        Caution: use these options at your own risk.  It is believed that some
        of them bite.

        -g                  Group option.

      Debug Options:
        -d, --debug         Print debug information
        -s, --sql           Print all SQL statements executed
        -e                  Print every action done

Ще один цікавий метод, зокрема під час програмної роботи з групами параметрів:

OptionParser.get_option_group(opt_str)

  Повертає `OptionGroup`, до якої належить короткий або довгий рядок параметрів opt_str (наприклад, `'-o'` або `'--option'`). Якщо такої `OptionGroup` немає, поверніть `None`.

### Друк рядка версії

Подібно до короткого рядка використання, `optparse` також може надрукувати рядок версії вашої програми. Ви повинні надати рядок як аргумент `version` для OptionParser:

    parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

`%prog` розгортається так само, як і в `usage`. Окрім цього, `версія` може містити все, що завгодно. Коли ви вказуєте його, `optparse` автоматично додає опцію `--version` до вашого аналізатора. Якщо він зустрічає цей параметр у командному рядку, він розгортає ваш рядок `version` (шляхом заміни `%prog`), друкує його в stdout і завершує роботу.

Наприклад, якщо ваш скрипт називається `/usr/bin/foo`:

    $ /usr/bin/foo --version
    foo 1.0

Наступні два методи можна використати для друку та отримання рядка `version`:

OptionParser.print_version(file=None)

  Вивести повідомлення про версію для поточної програми (`self.version`) у файл (стандартний вивід за замовчуванням). Як і у випадку з `print_usage()`, будь-яке входження `%prog` у `self.version` замінюється назвою поточної програми. Нічого не робить, якщо `self.version` порожній або невизначений.

OptionParser.get_version()

  Те саме, що `print_version()`, але повертає рядок версії замість її друку.

### Як `optparse` обробляє помилки

Є два широких класи помилок, про які `optparse` має турбуватися: помилки програміста та помилки користувача. Помилки програміста зазвичай є помилковими викликами `OptionParser.add_option()`, напр. недійсні рядки опцій, невідомі атрибути опцій, відсутні атрибути опцій тощо. З цими справляються звичайним способом: викликають виняток (або `optparse.OptionError` або `TypeError`) і дозволяють програмі аварійно завершувати роботу.

Обробка помилок користувача є набагато важливішою, оскільки вони гарантовано траплятимуться незалежно від того, наскільки стабільним є ваш код. `optparse` може автоматично виявляти деякі помилки користувача, такі як неправильні аргументи параметрів (передача `-n 4x`, де `-n` приймає цілочисельний аргумент), відсутні аргументи (`-n` у кінець командного рядка, де `-n` приймає аргумент будь-якого типу). Крім того, ви можете викликати `OptionParser.error()`, щоб повідомити про помилку, визначену програмою:

    (options, args) = parser.parse_args()
    ...
    if options.a and options.b:
        parser.error("options -a and -b are mutually exclusive")

У будь-якому випадку `optparse` обробляє помилку однаково: він друкує повідомлення про використання програми та повідомлення про помилку до стандартної помилки та виходить зі статусом помилки 2.

Розглянемо перший приклад вище, де користувач передає `4x` опції, яка приймає ціле число:

    $ /usr/bin/foo -n 4x
    Usage: foo [options]

    foo: error: option -n: invalid integer value: '4x'

Або, коли користувач взагалі не може передати значення:

    $ /usr/bin/foo -n
    Usage: foo [options]

    foo: error: -n option requires an argument

`optparse`-згенеровані повідомлення про помилку завжди вказують опцію, пов’язану з помилкою; обов’язково зробіть те саме під час виклику `OptionParser.error()` із коду програми.

Якщо стандартна поведінка обробки помилок `optparse` не відповідає вашим потребам, вам потрібно створити підклас OptionParser і перевизначити його `exit()` та/або `error()` методи.

### Зібравши все разом

Ось як зазвичай виглядають сценарії на основі `optparse`:

    from optparse import OptionParser
    ...
    def main():
        usage = "usage: %prog [options] arg"
        parser = OptionParser(usage)
        parser.add_option("-f", "--file", dest="filename",
                          help="read data from FILENAME")
        parser.add_option("-v", "--verbose",
                          action="store_true", dest="verbose")
        parser.add_option("-q", "--quiet",
                          action="store_false", dest="verbose")
        ...
        (options, args) = parser.parse_args()
        if len(args) != 1:
            parser.error("incorrect number of arguments")
        if options.verbose:
            print("reading %s..." % options.filename)
        ...

    if __name__ == "__main__":
        main()

## Довідковий посібник

### Створення аналізатора

Першим кроком у використанні `optparse` є створення екземпляра OptionParser.

class optparse.OptionParser(...)

  Конструктор OptionParser не має обов’язкових аргументів, але має декілька необов’язкових ключових аргументів. Ви завжди повинні передавати їх як аргументи ключового слова, тобто не покладайтеся на порядок, у якому оголошено аргументи.

  `використання` (за замовчуванням: `"%prog [параметри]"`)

    The usage summary to print when your program is run incorrectly or with a help option. When `optparse` prints the usage string, it expands `%prog` to `os.path.basename(sys.argv[0])` (or to `prog` if you passed that keyword argument). To suppress a usage message, pass the special value `optparse.SUPPRESS_USAGE`.

  `option_list` (за замовчуванням: `[]`)

    Список об’єктів Option для заповнення аналізатора. Опції в `option_list` додаються після будь-яких опцій в `standard_option_list` (атрибут класу, який може бути встановлений підкласами OptionParser), але перед будь-якою версією або опціями довідки. Застаріле; замість цього використовуйте `add_option()` після створення аналізатора.

  `option_class` (за замовчуванням: optparse.Option)

    Клас для використання під час додавання параметрів до аналізатора в `add_option()`.

  `version` (за замовчуванням: `None`)

    Рядок версії для друку, коли користувач вказує параметр версії. Якщо ви вказуєте справжнє значення для `version`, `optparse` автоматично додає опцію версії з єдиним рядком опції `--version`. Підрядок `%prog` розгортається так само, як і `usage`.

  `conflict_handler` (за замовчуванням: `"помилка"`)

    Вказує, що робити, коли параметри з конфліктуючими рядками параметрів додаються до аналізатора; див. розділ Конфлікти між варіантами.

  `опис` (за замовчуванням: `None`)

    Абзац тексту, що дає короткий огляд вашої програми. `optparse` переформатує цей абзац відповідно до поточної ширини терміналу та друкує його, коли користувач запитує допомогу (після `використання`, але перед списком параметрів).

  `formatter` (за замовчуванням: новий `IndentedHelpFormatter`)

    Екземпляр optparse.HelpFormatter, який використовуватиметься для друку тексту довідки. `optparse` надає два конкретних класи для цієї мети: IndentedHelpFormatter і TitledHelpFormatter.

  `add_help_option` (за замовчуванням: `True`)

    Якщо істина, `optparse` додасть параметр довідки (із рядками параметрів `-h` і `--help`) до аналізатора.

  `програма`

    Рядок для використання під час розширення `%prog` у `usage` і `version` замість `os.path.basename(sys.argv[0])`.

  `епілог` (за замовчуванням: `None`)

    Абзац тексту довідки для друку після довідки параметра.

### Заповнення аналізатора

Є кілька способів заповнити аналізатор параметрами. Кращим способом є використання `OptionParser.add_option()`, як показано в розділі Підручник. `add_option()` можна викликати одним із двох способів:

- передати йому екземпляр Option (як повертає `make_option()`)

- передайте йому будь-яку комбінацію позиційних і ключових аргументів, які прийнятні для `make_option()` (тобто для конструктора Option), і він створить екземпляр Option для вас

Іншою альтернативою є передача списку попередньо сконструйованих екземплярів Option конструктору OptionParser, як у:

    option_list = [
        make_option("-f", "--filename",
                    action="store", type="string", dest="filename"),
        make_option("-q", "--quiet",
                    action="store_false", dest="verbose"),
        ]
    parser = OptionParser(option_list=option_list)

(`make_option()` є фабричною функцією для створення екземплярів Option; наразі це псевдонім для конструктора Option. Майбутня версія `optparse` може розділити Option на кілька класів і `make_option()` вибере правильний клас для створення екземпляра. Не створюйте екземпляр Option безпосередньо.)

### Визначення варіантів

Кожен екземпляр Option представляє набір синонімічних рядків параметрів командного рядка, напр. `-f` і `--file`. Ви можете вказати будь-яку кількість коротких або довгих рядків параметрів, але ви повинні вказати принаймні один загальний рядок параметрів.

Канонічним способом створення екземпляра `Option` є метод `add_option()` `OptionParser`.

OptionParser.add_option(option)
OptionParser.add_option(*opt_str, attr=value, ...)

  Щоб визначити опцію лише за допомогою короткого рядка опції:

      parser.add_option("-f", attr=value, ...)

  І щоб визначити опцію лише з довгим рядком опції:

      parser.add_option("--foo", attr=value, ...)

  Ключові аргументи визначають атрибути нового об’єкта Option. Найважливішим атрибутом параметра є `action`, і він значною мірою визначає, які інші атрибути є доречними або необхідними. Якщо ви передаєте нерелевантні атрибути параметрів або не передаєте необхідні, `optparse` викликає виняток `OptionError`, пояснюючи вашу помилку.

  Дія параметра визначає, що робить `optparse`, коли він зустрічає цей параметр у командному рядку. Стандартні дії параметрів, жорстко закодовані в `optparse`:

  `"магазин"`

    зберегти аргумент цього параметра (за замовчуванням)

  `"store_const"`

    store a constant value, pre-set via `Option.const`

  `"store_true"`

    зберігати `Правда`

  `"store_false"`

    зберігати `False`

  `"додати"`

    додати аргумент цього параметра до списку

  `"append_const"`

    append a constant value to a list, pre-set via `Option.const`

  `"рахувати"`

    збільшити лічильник на одиницю

  `"зворотний виклик"`

    викликати вказану функцію

  `"допомога"`

    роздрукувати повідомлення про використання, включно з усіма параметрами та документацією до них

  (Якщо ви не вказали дію, за замовчуванням буде `"store"`. Для цієї дії ви також можете вказати атрибути параметрів `type` і `dest` див. Стандартні опційні дії.)

As you can see, most actions involve storing or updating a value somewhere. `optparse` always creates a special object for this, conventionally called `options`, which is an instance of `optparse.Values`.

class optparse.Values

  An object holding parsed argument names and values as attributes. Normally created by calling when calling `OptionParser.parse_args()`, and can be overridden by a custom subclass passed to the values argument of `OptionParser.parse_args()` (as described in Розбір аргументів).

Option arguments (and various other values) are stored as attributes of this object, according to the `dest` (destination) option attribute.

Наприклад, коли ви дзвоните

    parser.parse_args()

одна з перших речей, які робить `optparse`, це створює об’єкт `options`:

    options = Values()

Якщо один із параметрів цього синтаксичного аналізатора визначено за допомогою

    parser.add_option("-f", "--file", action="store", type="string", dest="filename")

а командний рядок, що аналізується, містить будь-яке з наступного:

    -ffoo
    -f foo
    --file=foo
    --file foo

тоді `optparse`, побачивши цю опцію, зробить еквівалент:

    options.filename = "foo"

Атрибути `type` і `dest` майже такі ж важливі, як і `action`, але `action` є єдиним такий, який має сенс для всіх варіантів.

### Атрибути варіантів

class optparse.Option

  A single command line argument, with various attributes passed by keyword to the constructor. Normally created with `OptionParser.add_option()` rather than directly, and can be overridden by a custom class via the option_class argument to `OptionParser`.

Наступні атрибути параметрів можна передати як ключові аргументи до `OptionParser.add_option()`. Якщо ви передаєте атрибут опції, який не має відношення до певної опції, або не передаєте потрібний атрибут опції, `optparse` викликає `OptionError`.

Option.action

  (за замовчуванням: `"магазин"`)

  Визначає поведінку `optparse`, коли цей параметр відображається в командному рядку; доступні параметри задокументовані тут.

Option.type

  (за замовчуванням: `"рядок"`)

  Тип аргументу, очікуваний цією опцією (наприклад, `"string"` або `"int"`); доступні типи опцій задокументовані тут.

Option.dest

  (за замовчуванням: отримано з рядків параметрів)

  Якщо дія опції передбачає запис або зміну значення десь, це вказує `optparse`, де його писати: `dest` називає атрибут об’єкта `options`, який `optparse` збирається, коли аналізує командний рядок.

Option.default

  Значення для призначення цього параметра, якщо параметр не відображається в командному рядку. Дивіться також `OptionParser.set_defaults()`.

Option.nargs

  (за замовчуванням: 1)

  Скільки аргументів типу `type` має споживатися, коли відображається цей параметр. Якщо > 1, `optparse` зберігатиме кортеж значень у `dest`.

Option.const

  Для дій, які зберігають постійне значення, постійне значення для збереження.

Option.choices

  Для параметрів типу `"вибір"`, список рядків, з яких користувач може вибрати.

Option.callback

  Для параметрів із дією `"callback"`, виклик якого потрібно викликати, коли цей параметр видно. Дивіться розділ Опція зворотних викликів для детальної інформації про аргументи, які передаються викликаному.

Option.callback_args
Option.callback_kwargs

  Додаткові позиційні та ключові аргументи для передачі в `callback` після чотирьох стандартних аргументів зворотного виклику.

Option.help

  Help text to print for this option when listing all available options after the user supplies a `help` option (such as `--help`). If no help text is supplied, the option will be listed without help text. To hide this option, use the special value `optparse.SUPPRESS_HELP`.

Option.metavar

  (за замовчуванням: отримано з рядків параметрів)

  Заміна аргументу(ів) опції для використання під час друку довідкового тексту. Перегляньте розділ Підручник для прикладу.

### Стандартні опційні дії

Усі різні опціональні дії мають дещо різні вимоги та наслідки. Більшість дій мають кілька відповідних атрибутів параметрів, які ви можете вказати, щоб керувати поведінкою `optparse`; деякі з них мають обов’язкові атрибути, які ви повинні вказати для будь-якої опції, що використовує цю дію.

- `"магазин"` [релевантний: `type`, `dest`, `nargs`, `choices`]

  За параметром має слідувати аргумент, який перетворюється на значення відповідно до `type` і зберігається в `dest`. Якщо `nargs` > 1, з командного рядка буде використано кілька аргументів; усе буде перетворено відповідно до `type` і збережено в `dest` як кортеж. Перегляньте розділ Типи стандартних варіантів.

  Якщо надано `choices` (список або кортеж рядків), типом за замовчуванням є `"choice"`.

  Якщо `type` не вказано, за замовчуванням буде `"string"`.

  Якщо `dest` не надано, `optparse` отримує призначення з першого довгого рядка параметрів (наприклад, `--foo-bar` передбачає `foo_bar`). Якщо довгих рядків параметрів немає, `optparse` отримує адресат із першого короткого рядка параметрів (наприклад, `-f` означає `f`).

  Приклад:

      parser.add_option("-f")
      parser.add_option("-p", type="float", nargs=3, dest="point")

  Під час аналізу командного рядка

      -f foo.txt -p 1 -3.5 4 -fbar.txt

  `optparse` встановить

      options.f = "foo.txt"
      options.point = (1.0, -3.5, 4.0)
      options.f = "bar.txt"

- `"store_const"` [потрібно: `const`; релевантний: `dest`]

  Значення `const` зберігається в `dest`.

  Приклад:

      parser.add_option("-q", "--quiet",
                        action="store_const", const=0, dest="verbose")
      parser.add_option("-v", "--verbose",
                        action="store_const", const=1, dest="verbose")
      parser.add_option("--noisy",
                        action="store_const", const=2, dest="verbose")

  Якщо відображається `--noisy`, `optparse` встановить

      options.verbose = 2

- `"store_true"` [релевантний: `dest`]

  Особливий випадок `"store_const"`, який зберігає `True` у `dest`.

- `"store_false"` [релевантний: `dest`]

  Подібно до `"store_true"`, але зберігає `False`.

  Приклад:

      parser.add_option("--clobber", action="store_true", dest="clobber")
      parser.add_option("--no-clobber", action="store_false", dest="clobber")

- `"append"` [релевантні: `type`, `dest`, `nargs`, `choices`]

  За параметром має слідувати аргумент, який додається до списку в `dest`. Якщо значення за замовчуванням для `dest` не вказано, порожній список створюється автоматично, коли `optparse` вперше зустрічає цей параметр у командному рядку. Якщо `nargs` > 1, споживаються кілька аргументів, а кортеж довжини `nargs` додається до `dest`.

  Значення за замовчуванням для `type` і `dest` такі самі, як і для дії `"store"`.

  Приклад:

      parser.add_option("-t", "--tracks", action="append", type="int")

  Якщо в командному рядку відображається `-t3`, `optparse` виконує еквівалент:

      options.tracks = []
      options.tracks.append(int("3"))

  Якщо трохи пізніше з’явиться `--tracks=4`, це так:

      options.tracks.append(int("4"))

  Дія `append` викликає метод `append` для поточного значення опції. Це означає, що будь-яке вказане значення за замовчуванням повинно мати метод `додавання`. Це також означає, що якщо значення за замовчуванням не є порожнім, елементи за замовчуванням будуть присутні в розібраному значенні для параметра, а будь-які значення з командного рядка будуть додані після цих значень за замовчуванням:

      >>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults'])
      >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg'])
      >>> opts.files
      ['~/.mypkg/defaults', 'overrides.mypkg']

- `"append_const"` [потрібно: `const`; релевантний: `dest`]

  Як `"store_const"`, але значення `const` додається до `dest`; як і у випадку з `"append"`, `dest` за замовчуванням має значення `None`, і порожній список автоматично створюється, коли вперше зустрічається опція.

- `"count"` [relevant: `dest`]

  Збільшити ціле число, що зберігається в `dest`. Якщо значення за замовчуванням не вказано, `dest` встановлюється на нуль перед першим збільшенням.

  Приклад:

      parser.add_option("-v", action="count", dest="verbosity")

  Коли `-v` з’являється в командному рядку вперше, `optparse` виконує еквівалент:

      options.verbosity = 0
      options.verbosity += 1

  Кожне наступне повторення `-v` призводить до:

      options.verbosity += 1

- `"callback"` [потрібно: `callback`; релевантні: `type`, `nargs`, `callback_args`, `callback_kwargs`]

  Виклик функції, визначеної `callback`, яка викликається як

      func(option, opt_str, value, parser, *args, **kwargs)

  Дивіться розділ Опція зворотних викликів для більш детальної інформації.

- `"допомога"`

  Друкує повне довідкове повідомлення для всіх параметрів у поточному аналізаторі параметрів. Повідомлення довідки складається з рядка `usage`, переданого конструктору OptionParser, і рядка `help`, переданого кожному параметру.

  If no `help` string is supplied for an option, it will still be listed in the help message. To omit an option entirely, use the special value `optparse.SUPPRESS_HELP`.

  `optparse` автоматично додає опцію `help` до всіх аналізаторів опцій, тому зазвичай вам не потрібно її створювати.

  Приклад:

      from optparse import OptionParser, SUPPRESS_HELP

      # usually, a help option is added automatically, but that can
      # be suppressed using the add_help_option argument
      parser = OptionParser(add_help_option=False)

      parser.add_option("-h", "--help", action="help")
      parser.add_option("-v", action="store_true", dest="verbose",
                        help="Be moderately verbose")
      parser.add_option("--file", dest="filename",
                        help="Input file to read data from")
      parser.add_option("--secret", help=SUPPRESS_HELP)

  Якщо `optparse` бачить або `-h`, або `--help` у командному рядку, він надрукує щось на кшталт наступного довідкового повідомлення до stdout (за умови `sys.argv[0]`).` є ``"foo.py"`):

      Usage: foo.py [options]

      Options:
        -h, --help        Show this help message and exit
        -v                Be moderately verbose
        --file=FILENAME   Input file to read data from

  Після друку довідкового повідомлення `optparse` завершує ваш процес за допомогою `sys.exit(0)`.

- `"версія"`

  Друкує номер версії, наданий OptionParser, у stdout і завершує роботу. Номер версії фактично форматується та друкується методом `print_version()` OptionParser. Зазвичай актуально, лише якщо аргумент `version` надається конструктору OptionParser. Як і у випадку з параметрами `help`, ви рідко будете створювати параметри `version`, оскільки `optparse` автоматично додає їх за потреби.

### Типи стандартних варіантів

`optparse` має п’ять вбудованих типів параметрів: `"string"`, `"int"`, `"choice"`, `"float"` і `"complex "`. Якщо вам потрібно додати нові типи опцій, перегляньте розділ Розширення optparse.

Аргументи параметрів рядка не перевіряються та не перетворюються жодним чином: текст у командному рядку зберігається в місці призначення (або передається зворотному виклику) як є.

Цілі аргументи (тип `"int"`) аналізуються таким чином:

- якщо число починається з `0x`, воно аналізується як шістнадцяткове число

- якщо число починається з `0`, воно аналізується як вісімкове число

- якщо число починається з `0b`, воно аналізується як двійкове число

- інакше число аналізується як десяткове число

Перетворення виконується викликом `int()` із відповідною основою (2, 8, 10 або 16). Якщо це не вдасться, не вийде і `optparse`, хоча з більш корисним повідомленням про помилку.

Аргументи параметрів `"float"` і `"complex"` перетворюються безпосередньо за допомогою `float()` і `complex()`, з подібною обробкою помилок.

Опції `"choice"` є підтипом опцій `"string"`. Атрибут опції `choices` (послідовність рядків) визначає набір дозволених аргументів опції. `optparse.check_choice()` порівнює аргументи параметрів, надані користувачем, із цим головним списком і викликає `OptionValueError`, якщо вказано недійсний рядок.

### Розбір аргументів

The whole point of creating and populating an OptionParser is to call its `parse_args()` method.

OptionParser.parse_args(args=None, values=None)

  Parse the command-line options found in args.

  The input parameters are

  `args`

    список аргументів для обробки (за замовчуванням: `sys.argv[1:]`)

  `значення`

    a `Values` object to store option arguments in (default: a new instance of `Values`) – if you give an existing object, the option defaults will not be initialized on it

  and the return value is a pair `(options, args)` where

  `параметри`

    the same object that was passed in as values, or the `optparse.Values` instance created by `optparse`

  `args`

    залишкові позиційні аргументи після обробки всіх опцій

The most common usage is to supply neither keyword argument. If you supply `values`, it will be modified with repeated `setattr()` calls (roughly one for every option argument stored to an option destination) and returned by `parse_args()`.

If `parse_args()` encounters any errors in the argument list, it calls the OptionParser’s `error()` method with an appropriate end-user error message. This ultimately terminates your process with an exit status of 2 (the traditional Unix exit status for command-line errors).

### Запити та маніпулювання вашим аналізатором параметрів

Поведінку аналізатора параметрів за замовчуванням можна дещо налаштувати, і ви також можете пошукати свій аналізатор параметрів і подивитися, що там є. OptionParser пропонує кілька методів, які допоможуть вам:

OptionParser.disable_interspersed_args()

  Встановіть зупинку аналізу на першому варіанті. Наприклад, якщо `-a` і `-b` є простими параметрами, які не приймають аргументів, `optparse` зазвичай приймає такий синтаксис:

      prog -a arg1 -b arg2

  і розглядає його як еквівалент

      prog -a -b arg1 arg2

  Щоб вимкнути цю функцію, викличте `disable_interspersed_args()`. Це відновлює традиційний синтаксис Unix, де розбір параметрів припиняється з першим аргументом, що не є параметром.

  Використовуйте це, якщо у вас є командний процесор, який виконує іншу команду, яка має власні параметри, і ви хочете переконатися, що ці параметри не плутаються. Наприклад, кожна команда може мати різний набір параметрів.

OptionParser.enable_interspersed_args()

  Налаштуйте розбір так, щоб він не зупинявся на першому не-параметрі, дозволяючи вставляти перемикачі в аргументи команди. Це типова поведінка.

OptionParser.get_option(opt_str)

  Повертає екземпляр Option із рядком параметра opt_str або `None`, якщо параметри не мають такого рядка параметра.

OptionParser.has_option(opt_str)

  Повертає `True`, якщо OptionParser має параметр із рядком параметра opt_str (наприклад, `-q` або `--verbose`).

OptionParser.remove_option(opt_str)

  Якщо `OptionParser` має параметр, що відповідає opt_str, цей параметр буде видалено. Якщо цей параметр містить будь-які інші рядки параметрів, усі ці рядки параметрів стають недійсними. Якщо opt_str не зустрічається в жодному параметрі, що належить цьому `OptionParser`, викликає `ValueError`.

### Конфлікти між варіантами

Якщо ви не будете обережні, можна легко визначити параметри з конфліктуючими рядками параметрів:

    parser.add_option("-n", "--dry-run", ...)
    ...
    parser.add_option("-n", "--noisy", ...)

(Це особливо вірно, якщо ви визначили свій власний підклас OptionParser з деякими стандартними параметрами.)

Кожного разу, коли ви додаєте опцію, `optparse` перевіряє наявність конфліктів із існуючими опціями. Якщо він знайде будь-який, він викликає поточний механізм обробки конфліктів. Ви можете встановити механізм обробки конфліктів у конструкторі:

    parser = OptionParser(..., conflict_handler=handler)

або окремим дзвінком:

    parser.set_conflict_handler(handler)

Доступні засоби обробки конфліктів:

> `"помилка"` (за замовчуванням)

>   припустити, що конфлікти параметрів є помилкою програмування, і викликати `OptionConflictError`

> `"розв'язати"`

>   розумно вирішувати конфлікти варіантів (див. нижче)

Як приклад, давайте визначимо `OptionParser`, який розумно вирішує конфлікти, і додамо до нього конфліктуючі параметри:

    parser = OptionParser(conflict_handler="resolve")
    parser.add_option("-n", "--dry-run", ..., help="do no harm")
    parser.add_option("-n", "--noisy", ..., help="be noisy")

At this point, `optparse` detects that a previously added option is already using the `-n` option string. Since `conflict_handler` is `"resolve"`, it resolves the situation by removing `-n` from the earlier option’s list of option strings. Now `--dry-run` is the only way for the user to activate that option. If the user asks for help, the help message will reflect that:

    Options:
      --dry-run     do no harm
      ...
      -n, --noisy   be noisy

It’s possible to whittle away the option strings for a previously added option until there are none left, and the user has no way of invoking that option from the command-line. In that case, `optparse` removes that option completely, so it doesn’t show up in help text or anywhere else. Carrying on with our existing OptionParser:

    parser.add_option("--dry-run", ..., help="new dry-run option")

На цьому етапі вихідний параметр `-n`/`--dry-run` більше не доступний, тому `optparse` видаляє його, залишаючи цей текст довідки:

    Options:
      ...
      -n, --noisy   be noisy
      --dry-run     new dry-run option

### Прибирати

Екземпляри OptionParser мають кілька циклічних посилань. Це не повинно бути проблемою для збирача сміття Python, але ви можете розірвати циклічні посилання явно, викликавши `destroy()` на вашому OptionParser, коли ви закінчите з цим. Це особливо корисно в довготривалих програмах, де великі об’єктні графіки доступні з вашого OptionParser.

### Інші методи

OptionParser підтримує кілька інших публічних методів:

OptionParser.set_usage(usage)

  Set the usage string according to the rules described above for the `usage` constructor keyword argument. Passing `None` sets the default usage string; use `optparse.SUPPRESS_USAGE` to suppress a usage message.

OptionParser.print_usage(file=None)

  Надрукувати повідомлення про використання для поточної програми (`self.usage`) у файл (стандартний вихід за замовчуванням). Будь-яке входження рядка `%prog` у `self.usage` замінюється назвою поточної програми. Нічого не робить, якщо `self.usage` порожній або не визначений.

OptionParser.get_usage()

  Те саме, що `print_usage()`, але повертає рядок використання замість його друку.

OptionParser.set_defaults(dest=value, ...)

  Встановіть значення за замовчуванням для кількох пунктів призначення одночасно. Використання `set_defaults()` є кращим способом встановлення значень за замовчуванням для параметрів, оскільки кілька параметрів можуть мати одне призначення. Наприклад, якщо кілька параметрів «режиму» встановлюють одне й те саме призначення, будь-який із них може встановити значення за замовчуванням, і виграє останній:

      parser.add_option("--advanced", action="store_const",
                        dest="mode", const="advanced",
                        default="novice")    # overridden below
      parser.add_option("--novice", action="store_const",
                        dest="mode", const="novice",
                        default="advanced")  # overrides above setting

  Щоб уникнути цієї плутанини, використовуйте `set_defaults()`:

      parser.set_defaults(mode="advanced")
      parser.add_option("--advanced", action="store_const",
                        dest="mode", const="advanced")
      parser.add_option("--novice", action="store_const",
                        dest="mode", const="novice")

## Опція зворотних викликів

Якщо вбудованих дій і типів `optparse` недостатньо для ваших потреб, у вас є два варіанти: розширити `optparse` або визначити опцію зворотного виклику. Розширення `optparse` є більш загальним, але надмірним для багатьох простих випадків. Досить часто простий зворотний дзвінок - це все, що вам потрібно.

Існує два кроки, щоб визначити опцію зворотного виклику:

- визначте саму опцію за допомогою дії `"callback"`

- написати зворотний дзвінок; це функція (або метод), яка приймає щонайменше чотири аргументи, як описано нижче

### Визначення опції зворотного виклику

Як завжди, найпростішим способом визначення опції зворотного виклику є використання методу `OptionParser.add_option()`. Окрім `action`, єдиним атрибутом параметра, який ви повинні вказати, є `callback`, функція для виклику:

    parser.add_option("-c", action="callback", callback=my_callback)

`callback` є функцією (або іншим викликаним об’єктом), тому ви повинні вже визначати `my_callback()`, створюючи цю опцію зворотного виклику. У цьому простому випадку `optparse` навіть не знає, чи `-c` приймає будь-які аргументи, що зазвичай означає, що опція не приймає аргументів — сама наявність `-c` на командний рядок — це все, що йому потрібно знати. Проте за деяких обставин ви можете захотіти, щоб ваш зворотній виклик споживав довільну кількість аргументів командного рядка. Тут написання зворотних викликів стає складним; це розглянуто далі в цьому розділі.

`optparse` завжди передає чотири конкретні аргументи вашому зворотному виклику, і він передасть додаткові аргументи, лише якщо ви вкажете їх через `callback_args` і `callback_kwargs`. Таким чином, мінімальна сигнатура функції зворотного виклику:

    def my_callback(option, opt, value, parser):

Чотири аргументи зворотного виклику описані нижче.

Є кілька інших атрибутів опції, які ви можете надати, коли визначаєте опцію зворотного виклику:

`type`

  має своє звичайне значення: як і з діями `"store"` або `"append"`, воно наказує `optparse` споживати один аргумент і перетворювати його на `type` . Замість того, щоб десь зберігати перетворені значення, `optparse` передає їх вашій функції зворотного виклику.

`nargs`

  також має своє звичайне значення: якщо його надано та > 1, `optparse` споживатиме аргументи `nargs`, кожен із яких має бути конвертованим у `type`. Потім він передає кортеж перетворених значень у ваш зворотній виклик.

`callback_args`

  кортеж додаткових позиційних аргументів для передачі зворотному виклику

`callback_kwargs`

  словник додаткових ключових аргументів для передачі зворотному виклику

### Як називаються зворотні виклики

Усі зворотні виклики викликаються наступним чином:

    func(option, opt_str, value, parser, *args, **kwargs)

де

`опція`

  це екземпляр Option, який викликає зворотний виклик

`opt_str`

  це рядок параметрів, який можна побачити в командному рядку, який запускає зворотний виклик. (Якщо використовувався скорочений довгий параметр, `opt_str` буде повним, канонічним рядком параметра — наприклад, якщо користувач розміщує `--foo` у командному рядку як скорочення для `-- foobar`, тоді `opt_str` буде `"--foobar"`.)

`значення`

  є аргументом цього параметра в командному рядку. `optparse` очікуватиме аргумент, лише якщо встановлено `type`; тип `значення` буде типом, який передбачається типом опції. Якщо `type` для цього параметра має значення `None` (аргумент не очікується), тоді `value` буде `None`. Якщо `nargs` > 1, `value` буде кортежем значень відповідного типу.

`парсер`

  це екземпляр OptionParser, який керує всім цим, головним чином корисний, оскільки ви можете отримати доступ до деяких інших цікавих даних через його атрибути екземпляра:

  `parser.largs`

    the current list of leftover arguments, ie. arguments that have been consumed but are neither options nor option arguments. Feel free to modify `parser.largs`, e.g. by adding more arguments to it. (This list will become `args`, the second return value of `parse_args()`.)

  `parser.rargs`

    поточний список аргументів, що залишилися, тобто. з вилученими параметрами `opt_str` і `value` (якщо застосовно), і залишаються лише наступні за ними аргументи. Не соромтеся змінити `parser.rargs`, напр. споживаючи більше аргументів.

  `parser.values`

    об’єкт, де за замовчуванням зберігаються значення параметрів (екземпляр optparse.OptionValues). Це дозволяє зворотним викликам використовувати той самий механізм, що й решта `optparse` для зберігання значень параметрів; вам не потрібно возитися з глобалами чи закриттями. Ви також можете отримати доступ або змінити значення будь-яких параметрів, які вже зустрічаються в командному рядку.

`args`

  це кортеж довільних позиційних аргументів, що надаються через атрибут опції `callback_args`.

`кварги`

  це словник довільних аргументів ключових слів, які надаються через `callback_kwargs`.

### Викликання помилок у зворотному виклику

Функція зворотного виклику має викликати `OptionValueError`, якщо є проблеми з параметром або його аргументом(ами). `optparse` вловлює це та завершує програму, друкуючи повідомлення про помилку, яке ви надаєте на stderr. Ваше повідомлення має бути ясним, лаконічним, точним і вказувати на помилковий варіант. В іншому випадку користувачеві буде важко зрозуміти, що він зробив не так.

### Приклад зворотного виклику 1: тривіальний зворотний виклик

Ось приклад опції зворотного виклику, яка не приймає аргументів і просто записує, що опцію було розглянуто:

    def record_foo_seen(option, opt_str, value, parser):
        parser.values.saw_foo = True

    parser.add_option("--foo", action="callback", callback=record_foo_seen)

Звичайно, ви можете зробити це за допомогою дії `"store_true"`.

### Приклад зворотного виклику 2: перевірте порядок варіантів

Ось трохи цікавіший приклад: зафіксуйте факт відображення `-a`, але роздуйте, якщо він стоїть після `-b` у командному рядку.

    def check_order(option, opt_str, value, parser):
        if parser.values.b:
            raise OptionValueError("can't use -a after -b")
        parser.values.a = 1
    ...
    parser.add_option("-a", action="callback", callback=check_order)
    parser.add_option("-b", action="store_true", dest="b")

### Приклад зворотного виклику 3: перевірка порядку опцій (узагальнено)

If you want to reuse this callback for several similar options (set a flag, but blow up if `-b` has already been seen), it needs a bit of work: the error message and the flag that it sets must be generalized.

    def check_order(option, opt_str, value, parser):
        if parser.values.b:
            raise OptionValueError("can't use %s after -b" % opt_str)
        setattr(parser.values, option.dest, 1)
    ...
    parser.add_option("-a", action="callback", callback=check_order, dest='a')
    parser.add_option("-b", action="store_true", dest="b")
    parser.add_option("-c", action="callback", callback=check_order, dest='c')

### Приклад зворотного виклику 4: перевірка довільної умови

Звичайно, ви можете поставити туди будь-яку умову — ви не обмежені перевіркою значень уже визначених параметрів. Наприклад, якщо у вас є опції, які не слід викликати в повний місяць, все, що вам потрібно зробити, це:

    def check_moon(option, opt_str, value, parser):
        if is_moon_full():
            raise OptionValueError("%s option invalid when moon is full"
                                   % opt_str)
        setattr(parser.values, option.dest, 1)
    ...
    parser.add_option("--foo",
                      action="callback", callback=check_moon, dest="foo")

(Визначення `is_moon_full()` залишено як вправа для читача.)

### Приклад зворотного виклику 5: фіксовані аргументи

Справи стають трохи цікавішими, коли ви визначаєте параметри зворотного виклику, які приймають фіксовану кількість аргументів. Вказівка того, що опція зворотного виклику приймає аргументи, подібна до визначення опції `"store"` або `"append"`: якщо ви визначаєте `type`, тоді опція приймає один аргумент, який повинен бути конвертованим у цей тип; якщо ви далі визначаєте `nargs`, тоді параметр приймає аргументи `nargs`.

Ось приклад, який просто емулює стандартну дію `"store"`:

    def store_value(option, opt_str, value, parser):
        setattr(parser.values, option.dest, value)
    ...
    parser.add_option("--foo",
                      action="callback", callback=store_value,
                      type="int", nargs=3, dest="foo")

Зауважте, що `optparse` піклується про споживання 3 аргументів і перетворення їх на цілі числа за вас; все, що вам потрібно зробити, це зберегти їх. (Або що завгодно; очевидно, вам не потрібен зворотний виклик для цього прикладу.)

### Приклад зворотного виклику 6: змінні аргументи

Справи стають заплутаними, коли ви хочете, щоб параметр приймав змінну кількість аргументів. У цьому випадку ви повинні написати зворотний виклик, оскільки `optparse` не надає жодних вбудованих можливостей для нього. І вам доведеться мати справу з певними тонкощами звичайного аналізу командного рядка Unix, який `optparse` зазвичай обробляє для вас. Зокрема, зворотні виклики мають реалізовувати звичайні правила для голих аргументів `--` і `-`:

- `--` або `-` можуть бути аргументами опції

- голий `--` (якщо не аргумент для якогось параметра): зупинити обробку командного рядка та відкинути `--`

- голий `-` (якщо не аргумент для якогось параметра): зупинити обробку командного рядка, але зберегти `-` (додати його до `parser.largs`)

Якщо вам потрібна опція, яка приймає змінну кількість аргументів, є кілька тонких, складних питань, про які варто потурбуватися. Точна реалізація, яку ви виберете, базуватиметься на компромісах, які ви готові зробити для своєї програми (саме тому `optparse` не підтримує подібні речі напряму).

Тим не менш, ось спроба зворотного виклику для опції зі змінними аргументами:

    def vararg_callback(option, opt_str, value, parser):
        assert value is None
        value = []

        def floatable(str):
            try:
                float(str)
                return True
            except ValueError:
                return False

        for arg in parser.rargs:
            # stop on --foo like options
            if arg[:2] == "--" and len(arg) > 2:
                break
            # stop on -a, but not on -3 or -3.0
            if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
                break
            value.append(arg)

        del parser.rargs[:len(value)]
        setattr(parser.values, option.dest, value)

    ...
    parser.add_option("-c", "--callback", dest="vararg_attr",
                      action="callback", callback=vararg_callback)

## Розширення `optparse`

Оскільки двома основними факторами, що впливають на те, як `optparse` інтерпретує параметри командного рядка, є дія та тип кожного параметра, найімовірнішим напрямком розширення є додавання нових дій і нових типів.

### Додавання нових типів

Щоб додати нові типи, вам потрібно визначити власний підклас класу `optparse` `Option`. Цей клас має кілька атрибутів, які визначають типи `optparse`: `TYPES` і `TYPE_CHECKER`.

Option.TYPES

  Кортеж імен типів; у своєму підкласі просто визначте новий кортеж `TYPES`, який базується на стандартному.

Option.TYPE_CHECKER

  Словник, що зіставляє назви типів із функціями перевірки типу. Функція перевірки типу має такий підпис:

      def check_mytype(option, opt, value)

  де `option` - це екземпляр `Option`, `opt` - це рядок параметра (наприклад, `-f`), а `value` - це рядок із командного рядка, який необхідно перевірити та перетворити на потрібний тип. `check_mytype()` має повертати об’єкт гіпотетичного типу `mytype`. Значення, повернуте функцією перевірки типу, з’явиться в екземплярі OptionValues, поверненому `OptionParser.parse_args()`, або буде передано зворотному виклику як параметр `value`.

  Ваша функція перевірки типу має викликати `OptionValueError`, якщо вона стикається з будь-якими проблемами. `OptionValueError` приймає один рядковий аргумент, який передається як є до методу `error()` `OptionParser`, який, у свою чергу, додає назву програми та рядок `"помилка: "` і друкує все в stderr перед завершенням процесу.

Ось дурний приклад, який демонструє додавання типу параметра `"complex"` для аналізу комплексних чисел у стилі Python у командному рядку. (Це ще безглуздіше, ніж було раніше, тому що `optparse` 1.3 додав вбудовану підтримку комплексних чисел, але нічого.)

По-перше, необхідний імпорт:

    from copy import copy
    from optparse import Option, OptionValueError

Спершу вам потрібно визначити свій засіб перевірки типів, оскільки на нього посилатимуться пізніше (в атрибуті класу `TYPE_CHECKER` вашого підкласу Option):

    def check_complex(option, opt, value):
        try:
            return complex(value)
        except ValueError:
            raise OptionValueError(
                "option %s: invalid complex value: %r" % (opt, value))

Нарешті, підклас Option:

    class MyOption (Option):
        TYPES = Option.TYPES + ("complex",)
        TYPE_CHECKER = copy(Option.TYPE_CHECKER)
        TYPE_CHECKER["complex"] = check_complex

(Якби ми не зробили `copy()` `Option.TYPE_CHECKER`, ми б завершили зміну атрибута `TYPE_CHECKER` параметра `optparse` Оскільки це Python, ніщо не заважає вам це зробити, крім хороших манер і здорового глузду.)

Це воно! Тепер ви можете написати сценарій, який використовує новий тип опцій, як і будь-який інший сценарій на основі `optparse`, за винятком того, що вам потрібно вказати вашому OptionParser використовувати MyOption замість Option:

    parser = OptionParser(option_class=MyOption)
    parser.add_option("-c", type="complex")

Крім того, ви можете створити власний список параметрів і передати його в OptionParser; якщо ви не використовуєте `add_option()` вищезгаданим способом, вам не потрібно вказувати OptionParser, який клас параметрів використовувати:

    option_list = [MyOption("-c", action="store", type="complex", dest="c")]
    parser = OptionParser(option_list=option_list)

### Додавання нових дій

Додавати нові дії трохи складніше, тому що ви повинні розуміти, що `optparse` має кілька класифікацій для дій:

дії «магазину».

  дії, які призводять до того, що `optparse` зберігає значення в атрибуті поточного екземпляра OptionValues; ці параметри вимагають надання атрибута `dest` конструктору Option.

«набрані» дії

  дії, які беруть значення з командного рядка та очікують, що воно буде певного типу; точніше, рядок, який можна перетворити на певний тип. Для цих параметрів потрібен атрибут `type` конструктору Option.

Це набори, що перекриваються: деякі дії «зберігання» за замовчуванням - це `"store"`, `"store_const"`, `"append"` і `"count"`, а за замовчуванням «typed» « діями є `"зберігати"`, `"додавати"` і `"зворотний виклик"`.

Коли ви додаєте дію, вам потрібно класифікувати її, перерахувавши принаймні в одному з наступних атрибутів класу Option (усі є списками рядків):

Option.ACTIONS

  Усі дії мають бути вказані в ACTIONS.

Option.STORE_ACTIONS

  тут додатково перераховані дії «магазину».

Option.TYPED_ACTIONS

  «введені» дії додатково перераховані тут.

Option.ALWAYS_TYPED_ACTIONS

  Дії, які завжди мають тип (тобто чиї параметри завжди приймають значення), додатково перераховані тут. Єдиним ефектом цього є те, що `optparse` призначає тип за замовчуванням, `"string"`, параметрам без явного типу, дія яких указана в `ALWAYS_TYPED_ACTIONS`.

Щоб фактично реалізувати вашу нову дію, ви повинні перевизначити метод `take_action()` Option і додати регістр, який розпізнає вашу дію.

Наприклад, давайте додамо дію `"розширити"`. Це схоже на стандартну дію `"append"`, але замість того, щоб брати одне значення з командного рядка та додавати його до існуючого списку, `"extend"` прийматиме кілька значень в одній комі -рядок із роздільниками та розширити ними існуючий список. Тобто, якщо `--names` є опцією `"extend"` типу `"string"`, командний рядок:

    --names=foo,bar --names blah --names ding,dong

призведе до списку

    ["foo", "bar", "blah", "ding", "dong"]

Знову ми визначаємо підклас Option:

    class MyOption(Option):

        ACTIONS = Option.ACTIONS + ("extend",)
        STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
        TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
        ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

        def take_action(self, action, dest, opt, value, values, parser):
            if action == "extend":
                lvalue = value.split(",")
                values.ensure_value(dest, []).extend(lvalue)
            else:
                Option.take_action(
                    self, action, dest, opt, value, values, parser)

Примітка.

- `"extend"` очікує значення в командному рядку та десь зберігає це значення, тому воно входить і в `STORE_ACTIONS`, і в `TYPED_ACTIONS`.

- щоб гарантувати, що `optparse` призначає типовий тип `"string"` діям `"extend"`, ми додаємо дію `"extend"` в `ALWAYS_TYPED_ACTIONS` також.

- `MyOption.take_action()` реалізує лише цю нову дію та передає керування назад `Option.take_action()` для стандартних дій `optparse`.

- `values` є екземпляром класу optparse_parser.Values, який надає дуже корисний метод `ensure_value()`. `ensure_value()` це по суті `getattr()` із запобіжним клапаном; це називається як

      values.ensure_value(attr, value)

  If the `attr` attribute of `values` doesn’t exist or is `None`, then ensure_value() first sets it to `value`, and then returns `value`. This is very handy for actions like `"extend"`, `"append"`, and `"count"`, all of which accumulate data in a variable and expect that variable to be of a certain type (a list for the first two, an integer for the latter). Using `ensure_value()` means that scripts using your action don’t have to worry about setting a default value for the option destinations in question; they can just leave the default as `None` and `ensure_value()` will take care of getting it right when it’s needed.

## Винятки

exception optparse.OptionError

  Raised if an `Option` instance is created with invalid or inconsistent arguments.

exception optparse.OptionConflictError

  Raised if conflicting options are added to an `OptionParser`.

exception optparse.OptionValueError

  Raised if an invalid option value is encountered on the command line.

exception optparse.BadOptionError

  Raised if an invalid option is passed on the command line.

exception optparse.AmbiguousOptionError

  Raised if an ambiguous option is passed on the command line.