optparse
— Анализатор параметров командной строки¶
Исходный код: Lib/optparse.py
Не рекомендуется, начиная с версии 3.2: Модуль optparse
устарел и не будет разрабатываться в дальнейшем; разработка будет продолжена с модулем argparse
.
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
был специально разработан для содействия созданию программ с простыми, традиционными интерфейсами командной строки. С этой целью он поддерживает только наиболее распространенный синтаксис и семантику командной строки, традиционно используемые в Unix. Если вы не знакомы с этими соглашениями, прочтите этот раздел, чтобы ознакомиться с ними.
Терминология¶
- аргумент
строка, введенная в командной строке и переданная командной оболочкой в
execl()
илиexecv()
. В Python аргументами являются элементыsys.argv[1:]
(sys.argv[0]
- это название выполняемой программы). В оболочках Unix также используется термин «word».Иногда желательно заменить список аргументов, отличный от
sys.argv[1:]
, поэтому вам следует читать «аргумент» как «элемент изsys.argv[1:]
или из какого-либо другого списка, предоставленного вместоsys.argv[1:]
».- вариант
аргумент, используемый для предоставления дополнительной информации, направляющей или настраивающей выполнение программы. Существует множество различных синтаксисов для опций; традиционный синтаксис Unix - это дефис («-«), за которым следует одна буква, например
-x
или-F
. Кроме того, традиционный синтаксис Unix позволяет объединить несколько параметров в один аргумент, например,-x -F
эквивалентно-xF
. В проекте GNU было введено--
, за которым следовал ряд слов, разделенных дефисом, например--file
или--dry-run
. Это единственные два варианта синтаксиса, предоставляемыеoptparse
.Некоторые другие варианты синтаксиса, которые видел мир, включают:
дефис, за которым следует несколько букв, например
-pf
(это не то же самое, что несколько параметров, объединенных в один аргумент)дефис, за которым следует целое слово, например
-file
(технически это эквивалентно предыдущему синтаксису, но обычно они не используются в одной и той же программе)знак «плюс», за которым следует одна буква, или несколько букв, или слово, например
+f
,+rgb
косая черта, за которой следует буква, или несколько букв, или слово, например
/f
,/file
Эти синтаксисы параметров не поддерживаются
optparse
и никогда не будут поддерживаться. Это сделано намеренно: первые три варианта являются нестандартными для любой среды, а последний имеет смысл только в том случае, если вы ориентируетесь исключительно на Windows или определенные устаревшие платформы (например, виртуальные машины, 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
является аргументом option. 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()
(Если хотите, вы можете передать пользовательский список аргументов в 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
принять следующий аргумент (или оставшуюся часть текущего аргумента), убедиться, что он имеет правильный тип, и сохранить его в выбранном вами месте назначения.
Например:
parser.add_option("-f", "--file",
action="store", type="string", dest="filename")
Теперь давайте создадим фальшивую командную строку и попросим optparse
разобрать ее:
args = ["-f", "foo.txt"]
(options, args) = 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 аргументу option: поскольку -n42
(один аргумент) эквивалентен -n 42
(два аргумента), код
(options, args) = parser.parse_args(["-n42"])
print(options.num)
выведет 42
.
Если вы не укажете тип, то optparse
будет означать string
. В сочетании с тем фактом, что действие по умолчанию равно 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
"append"
добавьте аргумент этого параметра в список
"count"
увеличьте счетчик на единицу
"callback"
вызов указанной функции
Они описаны в разделе Справочное руководство и разделе Опция обратного вызова.
Значения по умолчанию¶
Все приведенные выше примеры включают установку некоторой переменной («назначения»), когда отображаются определенные параметры командной строки. Что произойдет, если эти параметры никогда не отображаются? Поскольку мы не указали значения по умолчанию, все они имеют значение 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()
Как и прежде, учитывается последнее значение, указанное для данного параметра destination. Для наглядности попробуйте использовать тот или иной метод установки значений по умолчанию, а не оба сразу.
Создание справки¶
Возможность 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
в строке usage до названия текущей программы, т.е.os.path.basename(sys.argv[0])
. Затем расширенная строка выводится перед подробной справкой по параметрам.Если вы не указываете строку использования,
optparse
использует простое, но разумное значение по умолчанию:"Usage: %prog [options]"
, что нормально, если ваш скрипт не принимает никаких позиционных аргументов.каждая опция определяет строку справки и не заботится о переносе строк—
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)¶
где
синтаксический анализатор - это
OptionParser
экземпляр, в который будет вставлена группаназвание - это название группы
необязательное описание - это подробное описание группы
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
. Кроме того, version
может содержать все, что вам нравится. Когда вы вводите его, optparse
автоматически добавляет параметр --version
в ваш синтаксический анализатор. Если он обнаруживает этот параметр в командной строке, он расширяет вашу строку version
(заменяя %prog
), выводит ее в стандартный вывод и завершает работу.
Например, если ваш скрипт называется /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
обрабатывает ошибку одинаково: выводит сообщение об использовании программы и сообщение об ошибке в формате standard error и завершает работу со статусом ошибки 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 не содержит обязательных аргументов, но содержит ряд необязательных аргументов по ключевым словам. Вы всегда должны передавать их в качестве аргументов по ключевым словам, т.е. не полагаться на порядок, в котором объявлены аргументы.
usage
(по умолчанию:"%prog [options]"
)Сводка об использовании для печати при неправильном запуске вашей программы или при наличии опции справки. Когда
optparse
выводит строку usage, она расширяется от%prog
доos.path.basename(sys.argv[0])
(или доprog
, если вы передали этот аргумент ключевого слова). Чтобы скрыть сообщение об использовании, передайте специальное значениеoptparse.SUPPRESS_USAGE
.option_list
(по умолчанию:[]
)Список объектов Option для заполнения синтаксическим анализатором. Параметры в
option_list
добавляются после любых параметров вstandard_option_list
(атрибут класса, который может быть задан подклассами OptionParser), но перед любыми параметрами версии или справки. Не рекомендуется; вместо этого используйтеadd_option()
после создания синтаксического анализатора.option_class
(по умолчанию: optparse.Опция)Класс, который будет использоваться при добавлении параметров в синтаксический анализатор в
add_option()
.version
(по умолчанию:None
)Строка версии для печати, когда пользователь указывает параметр версии. Если вы указываете значение true для
version
,optparse
, автоматически добавляется параметр версии с единственной строкой параметров--version
. Подстрока%prog
раскрывается так же, как и дляusage
.conflict_handler
(по умолчанию:"error"
)Указывает, что делать, когда в синтаксический анализатор добавляются параметры с конфликтующими строками параметров; смотрите раздел Конфликты между вариантами.
description
(по умолчанию:None
)Абзац текста, содержащий краткий обзор вашей программы.
optparse
переформатируйте этот абзац, чтобы он соответствовал текущей ширине терминала, и распечатайте его, когда пользователь запросит справку (послеusage
, но перед списком опций).formatter
(по умолчанию: новыйIndentedHelpFormatter
)Экземпляр optparse.HelpFormatter, который будет использоваться для печати текста справки.
optparse
предоставляет два конкретных класса для этой цели: IndentedHelpFormatter и TitledHelpFormatter.add_help_option
(по умолчанию:True
)Если значение равно true,
optparse
добавит параметр справки (со строками параметров-h
и--help
) в синтаксический анализатор.prog
Строка, используемая при расширении
%prog
вusage
иversion
вместоos.path.basename(sys.argv[0])
.epilog
(по умолчанию:None
)Абзац текста справки для печати после опции help.
Заполнение анализатора¶
Существует несколько способов заполнить синтаксический анализатор параметрами. Предпочтительный способ - использовать OptionParser.add_option()
, как показано в разделе Руководство. add_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 напрямую.)
Определение параметров¶
Каждый экземпляр параметра представляет собой набор синонимичных строк параметров командной строки, например -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. Наиболее важным атрибутом option является
action
, и он в значительной степени определяет, какие другие атрибуты являются релевантными или обязательными. Если вы передадите нерелевантные атрибуты опции или не сможете передать требуемые,optparse
вызоветOptionError
исключение, объясняющее вашу ошибку.Действие параметра определяет, что будет делать
optparse
при появлении этого параметра в командной строке. Стандартными действиями параметра, жестко заданными вoptparse
, являются:"store"
сохраните аргумент этого параметра (по умолчанию)
"store_const"
сохраните постоянное значение, заданное с помощью
Option.const
"store_true"
хранить
True
"store_false"
хранить
False
"append"
добавьте аргумент этого параметра в список
"append_const"
добавьте постоянное значение в список, предварительно заданный с помощью
Option.const
"count"
увеличьте счетчик на единицу
"callback"
вызов указанной функции
"help"
распечатайте сообщение об использовании, включая все опции и документацию к ним
(Если вы не указываете действие, по умолчанию используется значение
"store"
. Для этого действия вы также можете указать атрибутыtype
иdest
; см. Стандартные действия с опциями.)
Как вы можете видеть, большинство действий связано с сохранением или обновлением значения где-либо. optparse
для этого всегда создается специальный объект, обычно называемый options
, который является экземпляром optparse.Values
.
- class optparse.Values¶
Объект, содержащий проанализированные имена аргументов и значения в качестве атрибутов. Обычно создается вызовом при вызове
OptionParser.parse_args()
и может быть переопределен пользовательским подклассом, передаваемым в аргумент values дляOptionParser.parse_args()
(как описано в Разбор аргументов).
Аргументы параметра (и различные другие значения) хранятся как атрибуты этого объекта в соответствии с атрибутом параметра dest
(назначение).
Например, когда вы звоните
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¶
(по умолчанию:
"store"
)Определяет поведение
optparse
, когда этот параметр отображается в командной строке; доступные параметры описаны в документации here.
- Option.type¶
(по умолчанию:
"string"
)Тип аргумента, ожидаемый для этого параметра (например,
"string"
или"int"
); доступные типы параметров задокументированы here.
- Option.dest¶
(по умолчанию: получено из строк параметров)
Если действие опции подразумевает запись или изменение значения где-либо, это указывает
optparse
, куда его записать:dest
называет атрибутoptions
объекта, которыйoptparse
создается при анализе командная строка.
- Option.default¶
Значение, которое следует использовать для назначения этого параметра, если этот параметр не отображается в командной строке. Смотрите также
OptionParser.set_defaults()
.
- Option.nargs¶
(по умолчанию: 1)
Сколько аргументов типа
type
должно быть использовано при отображении этой опции. Если > 1,optparse
будет сохранен набор значенийdest
.
- Option.const¶
Для действий, которые сохраняют постоянное значение, необходимо сохранить постоянное значение.
- Option.choices¶
Для параметров типа
"choice"
- список строк, из которых пользователь может выбирать.
- Option.callback¶
Для параметров с действием
"callback"
вызываемый параметр вызывается при появлении этого параметра. Смотрите раздел Опция обратного вызова для получения подробной информации об аргументах, передаваемых вызываемому элементу.
- Option.callback_args¶
- Option.callback_kwargs¶
Дополнительные аргументы позиции и ключевого слова для передачи в
callback
после четырех стандартных аргументов обратного вызова.
- Option.help¶
Текст справки для печати для этого параметра отображается при перечислении всех доступных параметров после того, как пользователь введет параметр
help
(например,--help
). Если текст справки не указан, параметр будет указан без текста справки. Чтобы скрыть эту опцию, используйте специальное значениеoptparse.SUPPRESS_HELP
.
- Option.metavar¶
(по умолчанию: получено из строк параметров)
Заменяет аргументы option, которые будут использоваться при печати текста справки. Пример приведен в разделе Руководство.
Стандартные действия с опциями¶
Различные действия с параметрами имеют несколько разные требования и эффекты. Большинство действий имеют несколько соответствующих атрибутов параметров, которые вы можете указать для управления поведением optparse
; у некоторых есть обязательные атрибуты, которые вы должны указать для любого параметра, использующего это действие.
"store"
[актуально: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
для текущего значения параметра. Это означает, что любое указанное значение по умолчанию должно иметь метод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"
[актуально: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)
Смотрите раздел Опция обратного вызова для получения более подробной информации.
"help"
Выводит полное справочное сообщение для всех параметров текущего анализатора параметров. Справочное сообщение создается из строки
usage
, передаваемой в конструктор Optionparser, и строкиhelp
, передаваемой в каждый параметр.Если для параметра не указана строка
help
, он все равно будет указан в справочном сообщении. Чтобы полностью исключить параметр, используйте специальное значениеoptparse.SUPPRESS_HELP
.optparse
автоматически добавляет параметрhelp
ко всем параметрам Optionparser, поэтому обычно вам не нужно его создавать.Пример:
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
, в стандартный вывод будет выведено что-то вроде следующего справочного сообщения (при условии, что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)
."version"
Выводит номер версии, переданный в OptionParser, в стандартный вывод и завершает работу. На самом деле номер версии отформатирован и напечатан с помощью
print_version()
метода OptionParser. Как правило, это актуально только в том случае, если в конструктор OptionParser передан аргументversion
. Как и в случае с параметрамиhelp
, вы редко будете создавать параметрыversion
, посколькуoptparse
автоматически добавляет их при необходимости.
Стандартные типы опций¶
optparse
имеет пять встроенных типов опций: "string"
, "int"
, "choice"
, "float"
и "complex"
. Если вам нужно добавить новые типы опций, смотрите раздел Расширение optparse.
Аргументы в string options никоим образом не проверяются и не преобразуются: текст в командной строке сохраняется в пункте назначения (или передается в callback) как есть.
Целочисленные аргументы (тип "int"
) обрабатываются следующим образом:
если число начинается с
0x
, оно преобразуется в шестнадцатеричное числоесли число начинается с
0
, оно преобразуется в восьмеричное числоесли число начинается с
0b
, оно анализируется как двоичное числов противном случае число анализируется как десятичное число
Преобразование выполняется путем вызова int()
с соответствующей базой (2, 8, 10 или 16). Если это не удается, то же самое происходит с optparse
, хотя и с более полезным сообщением об ошибке.
Аргументы параметров "float"
и "complex"
преобразуются непосредственно в float()
и complex()
с аналогичной обработкой ошибок.
"choice"
параметры являются подтипом параметров "string"
. Атрибут choices
option (последовательность строк) определяет набор допустимых аргументов параметра. optparse.check_choice()
сравнивает аргументы параметра, предоставленные пользователем, с этим основным списком и выдает OptionValueError
, если указана недопустимая строка.
Разбор аргументов¶
Весь смысл создания и заполнения OptionParser заключается в вызове его метода parse_args()
.
- OptionParser.parse_args(args=None, values=None)¶
Проанализируйте параметры командной строки, найденные в args.
Входными параметрами являются
args
список аргументов для обработки (по умолчанию:
sys.argv[1:]
)values
объект
Values
для хранения аргументов параметра (по умолчанию: новый экземплярValues
) - если вы укажете существующий объект, значения параметра по умолчанию не будут инициализированы для него
и возвращаемое значение представляет собой пару
(options, args)
, гдеoptions
тот же объект, который был передан как values, или экземпляр
optparse.Values
, созданный с помощьюoptparse
args
оставшиеся позиционные аргументы после обработки всех параметров
Чаще всего не указывается ни один из аргументов ключевого слова. Если вы указываете values
, он будет изменен с помощью повторных вызовов setattr()
(примерно по одному для каждого аргумента option, сохраненного в пункте назначения option) и возвращен с помощью parse_args()
.
Если parse_args()
обнаруживает какие-либо ошибки в списке аргументов, он вызывает метод OptionParser error()
с соответствующим сообщением об ошибке конечного пользователя. Это в конечном итоге завершает ваш процесс со статусом завершения, равным 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)¶
Возвращает экземпляр параметра со строкой параметра 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"
(по умолчанию)предположим, что конфликты параметров являются программной ошибкой и вызывают
OptionConflictError
"resolve"
разумно разрешайте конфликты параметров (см. ниже).
В качестве примера давайте определим параметр 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
- это единственный способ для пользователя активировать эту опцию. Если пользователь обратится за помощью, в справочном сообщении будет указано, что:
Options:
--dry-run do no harm
...
-n, --noisy be 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()
является предпочтительным способом установки значений по умолчанию для параметров, поскольку несколько параметров могут использовать один и тот же адресат. Например, если несколько параметров «mode» задают один и тот же пункт назначения, любой из них может установить значение по умолчанию, и победит последний: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
это строка параметров, отображаемая в командной строке, которая запускает обратный вызов. (Если был использован сокращенный вариант long,
opt_str
будет полной, канонической строкой параметров—например, если пользователь вводит--foo
в командной строке в качестве сокращения для--foobar
, тоopt_str
будет"--foobar"
.)value
является аргументом для этой опции, отображаемым в командной строке.
optparse
будет ожидать аргумент только в том случае, если задано значениеtype
; типvalue
будет соответствовать типу, указанному в параметре type. Еслиtype
для этого параметра равноNone
(аргумент не ожидается), тоvalue
будет равноNone
. Ifnargs
> 1,value
будет представлять собой набор значений соответствующего типа.parser
является ли экземпляр OptionParser управляющим всем этим, в основном полезным, потому что вы можете получить доступ к некоторым другим интересным данным через атрибуты его экземпляра:
parser.largs
текущий список оставшихся аргументов, т.е. аргументов, которые были использованы, но не являются ни параметрами, ни аргументами option. Не стесняйтесь изменять
parser.largs
, например, добавляя к нему дополнительные аргументы. (Этот список станетargs
, вторым возвращаемым значениемparse_args()
.)parser.rargs
текущий список оставшихся аргументов, т.е. с
opt_str
иvalue
(если применимо) удалены, и только аргументы, следующие за ними, все еще присутствуют. Не стесняйтесь изменятьparser.rargs
, например, используя больше аргументов.parser.values
объект, в котором по умолчанию хранятся значения параметров (экземпляр optparse.Значения параметров). Это позволяет обратным вызовам использовать тот же механизм, что и остальные
optparse
для хранения значений параметров; вам не нужно возиться с глобальными параметрами или замыканиями. Вы также можете получить доступ к любым параметрам, уже имеющимся в командной строке, или изменить их значения.
args
представляет собой набор произвольных позиционных аргументов, предоставляемых с помощью атрибута
callback_args
option.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
принимает единственный строковый аргумент, который передается как есть методуOptionParser
, который,error()
в свою очередь, добавляет название программы и строку"error:"
и выводит все в stderr перед завершением процесса.
Вот глупый пример, демонстрирующий добавление параметра "complex"
для синтаксического анализа комплексных чисел в стиле Python в командной строке. (Это еще глупее, чем было раньше, потому что в optparse
1.3 добавлена встроенная поддержка комплексных чисел, но не обращайте внимания.)
Во-первых, необходимый импорт:
from copy import copy
from optparse import Option, OptionValueError
Сначала вам нужно определить свой инструмент проверки типов, поскольку он упоминается позже (в атрибуте TYPE_CHECKER
class вашего подкласса 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
класса Option optparse
. Поскольку это Python, ничто не мешает вам делать это, кроме хороших манер и здравого смысла.)
Вот и все! Теперь вы можете написать скрипт, который использует новый тип option точно так же, как и любой другой скрипт на основе 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
сохранению значения атрибута текущего экземпляра Option Values; для этих параметров требуется, чтобы атрибутdest
был передан конструктору Option.- «типизированные» действия
действия, которые принимают значение из командной строки и ожидают, что оно будет определенного типа; или, скорее, строка, которая может быть преобразована в определенный тип. Для этих параметров требуется атрибут
type
в конструкторе параметров.
Это перекрывающиеся наборы: некоторые «сохраняемые» действия по умолчанию - это "store"
, "store_const"
, "append"
, и "count"
, в то время как «типизированные» действия по умолчанию - это "store"
, "append"
и "callback"
.
Когда вы добавляете действие, вам необходимо классифицировать его, указав хотя бы в одном из следующих атрибутов класса Option (все они являются списками строк).:
- Option.ACTIONS¶
Все действия должны быть перечислены в разделе ДЕЙСТВИЯ.
- Option.STORE_ACTIONS¶
здесь также перечислены действия «сохранить».
- Option.TYPED_ACTIONS¶
здесь также перечислены «типизированные» действия.
- Option.ALWAYS_TYPED_ACTIONS¶
Здесь также перечислены действия, которые всегда имеют определенный тип (т.е. параметры которых всегда имеют значение). Единственным результатом этого является то, что
optparse
присваивает тип по умолчанию,"string"
, параметрам без явного типа, действие которых указано вALWAYS_TYPED_ACTIONS
.
Чтобы на самом деле реализовать ваше новое действие, вы должны переопределить метод Option take_action()
и добавить регистр, который распознает ваше действие.
Например, давайте добавим действие "extend"
. Это похоже на стандартное действие "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
, то ensure_value() сначала присваивает ему значениеvalue
, а затем возвращает значение „. Это очень удобно для таких действий, как"extend"
,"append"
, и"count"
, которые накапливают данные в переменной и ожидают, что переменная будет определенного типа (список для первых двух, целое число для последнего). Использованиеensure_value()
означает, что скриптам, использующим ваше действие, не нужно беспокоиться о том, чтобы установить значение по умолчанию для соответствующих назначений параметров; они могут просто оставить значение по умолчанию равнымNone
, аensure_value()
позаботятся о том, чтобы все было правильно когда это необходимо.
Исключения¶
- exception optparse.OptionError¶
Вызывается, если создается экземпляр
Option
с недопустимыми или несогласованными аргументами.
- exception optparse.OptionConflictError¶
Вызывается, если к
OptionParser
добавляются конфликтующие параметры.
- exception optparse.OptionValueError¶
Вызывается, если в командной строке обнаружено недопустимое значение параметра.
- exception optparse.BadOptionError¶
Возникает, если в командной строке передан недопустимый параметр.
- exception optparse.AmbiguousOptionError¶
Вызывается, если в командной строке передан неоднозначный параметр.