optparse — Анализатор параметров командной строки

Kod źródłowy: Lib/optparse.py


Escolhendo uma biblioteca de análise de linha de comando

A biblioteca padrão inclui três bibliotecas de análise de argumentos:

  • getopt: um módulo que espelha de perto a API procedural C getopt. Incluído na biblioteca padrão desde antes do lançamento inicial do Python 1.0.

  • optparse: декларативная замена getopt, которая обеспечивает эквивалентную функциональность, не требуя от каждого приложения реализации собственной процедурной логики анализа опций. Включено в стандартную библиотеку с момента выпуска Python 2.3.

  • argparse: более самоуверенная альтернатива optparse, которая по умолчанию обеспечивает больше функциональности за счет снижения гибкости приложения в точном контроле обработки аргументов. Включен в стандартную библиотеку начиная с выпусков Python 2.7 и Python 3.2.

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

getopt сохранен почти полностью по причинам обратной совместимости. Однако он также служит нишевым вариантом использования в качестве инструмента для прототипирования и тестирования обработки аргументов командной строки в приложениях на языке C на основе getopt.

optparse deve ser considerado como uma alternativa ao argparse nos seguintes casos:

  • uma aplicação já está usando optparse e não quer arriscar as sutis mudanças comportamentais que podem surgir ao migrar para argparse

  • a aplicação requer controle adicional sobre a maneira como as opções e os parâmetros posicionais são intercalados na linha de comando (incluindo a capacidade de desabilitar completamente o recurso de intercalação)

  • приложению требуется дополнительный контроль над инкрементальным анализом элементов командной строки (хотя argparse поддерживает это, точный способ, которым это работает на практике, нежелателен для некоторых случаев использования)

  • приложению требуется дополнительный контроль над обработкой параметров, которые принимают значения параметров, которые могут начинаться с - (например, делегированные параметры, которые должны быть переданы вызываемым подпроцессам)

  • приложению требуется некоторое другое поведение обработки параметров командной строки, которое argparse не поддерживает, но которое может быть реализовано в терминах низкоуровневого интерфейса, предлагаемого optparse

Essas considerações também significam que optparse provavelmente fornecerá uma base melhor para autores de bibliotecas que escrevem bibliotecas de processamento de argumentos de linha de comando de terceiros.

Como exemplo concreto, considere as duas configurações de análise de argumentos de linha de comando a seguir, a primeira usando optparse e a segunda usando argparse:

import optparse

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-o', '--output')
    parser.add_option('-v', dest='verbose', action='store_true')
    opts, args = parser.parse_args()
    process(args, output=opts.output, verbose=opts.verbose)
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output')
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.add_argument('rest', nargs='*')
    args = parser.parse_args()
    process(args.rest, output=args.output, verbose=args.verbose)

Наиболее очевидное отличие состоит в том, что в версии optparse аргументы, не являющиеся параметрами, обрабатываются приложением отдельно после завершения обработки параметра. В версии argparse позиционные аргументы объявляются и обрабатываются так же, как именованные параметры.

No entanto, a versão argparse também manipulará algumas combinações de parâmetros de forma diferente da forma como a versão optparse as manipularia. Por exemplo (entre outras diferenças):

  • указание -o -v дает output="-v" и verbose=False при использовании optparse, но ошибку использования с argparse (жалоба на то, что не было указано значение для -o/--output, поскольку -v интерпретируется как флаг многословности)

  • аналогично, предоставление -o -- дает output="--" и args=() при использовании optparse, но ошибка использования с argparse ( также жалуется, что для -o/--output не было указано значение, поскольку -- интерпретируется как прекращение обработки опции и обработка всех оставшихся значений как позиционных аргументов)

  • fornecer -o=foo retorna output="=foo" ao usar optparse, mas retorna output="foo" com argparse (já que = é um caso especial como um separador alternativo para valores de parâmetros de opção)

Se esses comportamentos diferentes na versão argparse são considerados desejáveis ou um problema dependerá do caso de uso específico da aplicação de linha de comando.

Zobacz także

click é uma biblioteca de processamento de argumentos de terceiros (originalmente baseada em optparse), que permite que aplicações de linha de comando sejam desenvolvidas como um conjunto de funções de implementação de comando decoradas.

Другие сторонние библиотеки, такие как typer или msgspec-click, позволяют указывать интерфейсы командной строки способами, которые более эффективно интегрируются со статической проверкой аннотаций типов Python.

Wprowadzenie

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

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

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

(options, args) = parser.parse_args()

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

<yourscript> --file=outfile -q

При анализе командной строки optparse устанавливает атрибуты объекта options, возвращаемого parse_args(), на основе значений командной строки, предоставленных пользователем. Когда parse_args() возвращается после анализа этой командной строки, options.filename будет outfile'`, а ``options.verbose будет False. optparse поддерживает как длинные, так и короткие параметры, позволяет объединять короткие параметры и связывать параметры с их аргументами различными способами. Таким образом, следующие командные строки эквивалентны приведенному выше примеру:

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

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

<yourscript> -h
<yourscript> --help

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

Usage: <yourscript> [options]

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

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

Фон

optparse был специально разработан для поощрения создания программ с простыми интерфейсами командной строки, которые следуют соглашениям, установленным семейством функций getopt(), доступных разработчикам C. С этой целью он поддерживает только наиболее распространенный синтаксис и семантику командной строки, традиционно используемые в Unix. Если вы не знакомы с этими соглашениями, прочтение этого раздела позволит вам ознакомиться с ними.

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

argument

рядок, введений у командному рядку та переданий оболонкою до 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 не підтримує цю функцію.

positional argument

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

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

параметр, який необхідно вказати в командному рядку; зауважте, що фраза „необхідна опція” є суперечливою англійською мовою. 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 окремих фрагментів інформації для успішної роботи, не має великого значення як ви отримуєте цю інформацію від користувача — більшість людей здадуться та підуть, перш ніж вони успішно запустять програму. Це стосується незалежно від того, чи є інтерфейс користувача командним рядком, файлом конфігурації чи графічним інтерфейсом користувача: якщо ви поставите стільки вимог до своїх користувачів, більшість із них просто здадуться.

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

Tutorial

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

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

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

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

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

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

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

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

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

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

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

(options, args) = parser.parse_args()

(Если хотите, вы можете передать parse_args() собственный список аргументов, но это редко бывает необходимо: по умолчанию он использует sys.argv[1:].)

parse_args() возвращает два значения:

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

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

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

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

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

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

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

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

Dla przykładu:

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

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

args = ["-f", "foo.txt"] (опции, аргументы) = parser.parse_args(args)

Когда optparse видит строку параметра -f, он принимает следующий аргумент, foo.txt, и сохраняет его в options.filename. Итак, после этого вызова parse_args() options.filename будет "foo.txt".

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

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

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

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

(опции, аргументы) = parser.parse_args(["-n42"]) печать(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"

сохранить постоянное значение, предварительно установленное через 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: останнє значення за замовчуванням, надане для будь-якого конкретного призначення, є тим, яке враховується.

Более понятный способ указать значения по умолчанию — это метод set_defaults() OptionParser, который вы можете вызвать в любое время перед вызовом parse_args():

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

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

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

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

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

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

Usage: <yourscript> [options] arg1 arg2

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

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

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

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

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

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

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

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

  • параметры, принимающие значения, указывают этот факт в автоматически создаваемом справочном сообщении, например, для параметра «режим»:

    -m MODE, --mode=MODE
    

    Здесь «MODE» называется метапеременной: она обозначает аргумент, который пользователь должен передать в -m/--mode. По умолчанию optparse преобразует имя целевой переменной в верхний регистр и использует его для метапеременной. Иногда это не то, что вам нужно — например, опция --filename явно устанавливает metavar="FILE", в результате чего автоматически генерируется следующее описание опции:

    -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(), щоб повідомити про помилку, визначену програмою:

(опции, аргументы) = parser.parse_args() ... если options.a и options.b: parser.error("Параметры -a и -b являются взаимоисключающими")

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

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

$ /usr/bin/foo -n 4x Использование: foo [опции] foo: ошибка: опция -n: неверное целое значение: '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 [параметри]")

Сводка использования, которая будет распечатана, если ваша программа запускается неправильно или с помощью опции справки. Когда optparse печатает строку использования, она расширяет `` %p rog`` в os.path.basename(sys.argv[0]) (или в prog, если вы передали этот аргумент ключевого слова). Чтобы подавить сообщение об использовании, передайте специальное значение 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

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

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

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

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

Є кілька способів заповнити аналізатор параметрами. Кращим способом є використання OptionParser.add_option(), як показано в розділі Tutorial. 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"

сохранить постоянное значение, предварительно установленное через Option.const

"store_true"

store True

"store_false"

store False

"додати"

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

"append_const"

добавить постоянное значение в список, предварительно установленное с помощью Option.const

"рахувати"

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

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

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

"допомога"

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

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

Как видите, большинство действий подразумевают сохранение или обновление значения где-либо. optparse всегда создаёт для этого специальный объект, условно называемый options, который является экземпляром optparse.Values.

class optparse.Values

Объект, содержащий имена и значения анализируемых аргументов в качестве атрибутов. Обычно создается путем вызова при вызове OptionParser.parse_args() и может быть переопределен пользовательским подклассом, передаваемым в аргумент values OptionParser.parse_args() (как описано в optparse-parsing) -аргументы).

Аргументы опции (и различные другие значения) сохраняются как атрибуты этого объекта в соответствии с атрибутом опции dest (destination).

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

parser.parse_args()

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

options = Values()

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

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

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

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

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

options.filename = "foo"

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

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

class optparse.Option

Один аргумент командной строки с различными атрибутами, передаваемыми конструктору по ключевому слову. Обычно создается с помощью OptionParser.add_option(), а не напрямую, и может быть переопределен пользовательским классом через аргумент option_class для OptionParser.

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

Option.action

(default: "store")

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

Option.type

(default: "string")

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

Option.dest

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

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

Option.default

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

Option.nargs

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

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

Option.const

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

Option.choices

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

Option.callback

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

Option.callback_args
Option.callback_kwargs

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

Option.help

Текст справки, который будет распечатан для этой опции при перечислении всех доступных опций после того, как пользователь укажет опцию help (например, --help). Если текст справки не указан, параметр будет указан без текста справки. Чтобы скрыть эту опцию, используйте специальное значение optparse.SUPPRESS_HELP.

Option.metavar

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

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

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

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

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

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

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

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

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

    Przykład:

    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.

    Przykład:

    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.

    Przykład:

    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".

    Przykład:

    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 встановлюється на нуль перед першим збільшенням.

    Przykład:

    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, переданого кожному параметру.

    Если для параметра не указана строка help, она все равно будет указана в справочном сообщении. Чтобы полностью опустить опцию, используйте специальное значение optparse.SUPPRESS_HELP.

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

    Przykład:

    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, якщо вказано недійсний рядок.

Parsowanie argumentów

Весь смысл создания и заполнения OptionParser заключается в вызове его метода parse_args().

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

Проанализируйте параметры командной строки, найденные в args.

Входные параметры:

args

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

значення

объект Values для хранения аргументов опции (по умолчанию: новый экземпляр Values) — если вы передадите существующий объект, параметры по умолчанию не будут инициализированы для него.

и возвращаемое значение представляет собой пару (options, args), где

параметри

тот же объект, который был передан как values, или экземпляр optparse.Values, созданный optparse

args

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

Наиболее распространенным использованием является отсутствие аргументов ключевого слова. Если вы предоставите значения, они будут изменены с помощью повторных вызовов setattr() (примерно по одному для каждого аргумента опции, хранящейся в пункте назначения опции) и возвращены parse_args().

Если parse_args() обнаруживает какие-либо ошибки в списке аргументов, он вызывает метод error() OptionParser с соответствующим сообщением об ошибке конечного пользователя. В конечном итоге ваш процесс завершается со статусом завершения 2 (традиционный статус завершения Unix для ошибок командной строки).

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

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

OptionParser.disable_interspersed_args()

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

prog -a arg1 -b arg2

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

prog -a -b arg1 arg2

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

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

OptionParser.enable_interspersed_args()

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

OptionParser.get_option(opt_str)

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

OptionParser.has_option(opt_str)

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

OptionParser.remove_option(opt_str)

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

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

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

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

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

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

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

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

parser.set_conflict_handler(handler)

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

"error" (default)

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

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

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

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

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

На этом этапе optparse обнаруживает, что ранее добавленная опция уже использует строку опции -n. Поскольку conflict_handler имеет "resolve", он разрешает ситуацию, удаляя -n из списка строк параметров предыдущей опции. Теперь --dry-run — единственный способ активировать эту опцию для пользователя. Если пользователь обращается за помощью, в справочном сообщении будет указано следующее:

Параметры: --dry-run не навредит ... -n, --noisy быть шумным

Можно свести на нет строки параметров для ранее добавленного параметра до тех пор, пока их не останется, и у пользователя не будет возможности вызвать этот параметр из командной строки. В этом случае optparse полностью удаляет эту опцию, поэтому она не отображается в тексте справки или где-либо еще. Продолжаем использовать существующий OptionParser:

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

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

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

Прибирати

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

Інші методи

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

OptionParser.set_usage(usage)

Установите строку использования в соответствии с правилами, описанными выше для аргумента ключевого слова конструктора usage. Передача None устанавливает строку использования по умолчанию; используйте optparse.SUPPRESS_USAGE для подавления сообщения об использовании.

OptionParser.print_usage(file=None)

Надрукувати повідомлення про використання для поточної програми (self.usage) у файл (стандартний вихід за замовчуванням). Будь-яке входження рядка %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

текущий список оставшихся аргументов, т.е. аргументы, которые были использованы, но не являются ни опциями, ни аргументами опций. Не стесняйтесь изменять parser.largs, например, добавляя к нему дополнительные аргументы. (Этот список станет args, вторым возвращаемым значением parse_args().)

parser.rargs

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

parser.values

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

args

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

kwargs

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

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

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

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

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

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

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

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

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

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

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

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

Если вы хотите повторно использовать этот обратный вызов для нескольких похожих опций (установить флаг, но разобрать, если -b уже был замечен), необходимо немного поработать: сообщение об ошибке и флаг, который он устанавливает, должны быть обобщенный.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Розширення optparse

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

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

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

Option.TYPES

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

Option.TYPE_CHECKER

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

def check_mytype(option, opt, value)

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

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

    Если атрибут attr для values не существует или имеет значение None, то метод обеспечения_value() сначала устанавливает его в value, а затем возвращает value. Это очень удобно для таких действий, как «расширить», «добавить» и «подсчитать», которые накапливают данные в переменной и ожидают, что эта переменная будет определенного типа. (список для первых двух, целое число для последнего). Использование ensure_value() означает, что скриптам, использующим ваше действие, не нужно беспокоиться об установке значения по умолчанию для рассматриваемых пунктов назначения; они могут просто оставить значение по умолчанию «Нет», и ensure_value() позаботится о том, чтобы все было правильно, когда это необходимо.

Wyjątki

exception optparse.OptionError

Возникает, если экземпляр Option создан с недопустимыми или противоречивыми аргументами.

exception optparse.OptionConflictError

Возникает, если в OptionParser добавлены конфликтующие параметры.

exception optparse.OptionValueError

Возникает, если в командной строке обнаружено недопустимое значение параметра.

exception optparse.BadOptionError

Возникает, если в командной строке передан недопустимый параметр.

exception optparse.AmbiguousOptionError

Возникает, если в командной строке передается неоднозначная опция.