optparse
— Parser for command line options¶
Вихідний код: Lib/optparse.py
Застаріло починаючи з версії 3.2: The optparse
module is deprecated and will not be developed further;
development will continue with the argparse
module.
optparse
— це більш зручна, гнучка та потужна бібліотека для аналізу параметрів командного рядка, ніж старий модуль getopt
. optparse
використовує більш декларативний стиль аналізу командного рядка: ви створюєте екземпляр OptionParser
, заповнюєте його параметрами та аналізуєте командний рядок. optparse
дозволяє користувачам вказувати параметри у звичайному синтаксисі GNU/POSIX, а також створює для вас повідомлення про використання та довідку.
Ось приклад використання optparse
у простому сценарії:
from optparse import OptionParser
...
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="don't print status messages to stdout")
(options, args) = parser.parse_args()
За допомогою цих кількох рядків коду користувачі вашого сценарію тепер можуть виконувати «звичайні дії» в командному рядку, наприклад:
<yourscript> --file=outfile -q
As it parses the command line, optparse
sets attributes of the
options
object returned by parse_args()
based on user-supplied
command-line values. When parse_args()
returns from parsing this command
line, options.filename
will be "outfile"
and options.verbose
will be
False
. optparse
supports both long and short options, allows short
options to be merged together, and allows options to be associated with their
arguments in a variety of ways. Thus, the following command lines are all
equivalent to the above example:
<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile
Крім того, користувачі можуть запустити одну з таких команд:
<yourscript> -h
<yourscript> --help
і optparse
виведе короткий опис параметрів вашого сценарію:
Usage: <yourscript> [options]
Options:
-h, --help show this help message and exit
-f FILE, --file=FILE write report to FILE
-q, --quiet don't print status messages to stdout
де значення yourscript визначається під час виконання (зазвичай із sys.argv[0]
).
Фон¶
optparse
був спеціально розроблений, щоб заохочувати створення програм із простими звичайними інтерфейсами командного рядка. З цією метою він підтримує лише найпоширеніший синтаксис і семантику командного рядка, які зазвичай використовуються в Unix. Якщо ви не знайомі з цими умовними поняттями, прочитайте цей розділ, щоб ознайомитися з ними.
Термінологія¶
- аргумент
рядок, введений у командному рядку та переданий оболонкою до
execl()
абоexecv()
. У Python аргументи є елементамиsys.argv[1:]
(sys.argv[0]
це ім’я програми, що виконується). Оболонки Unix також використовують термін «слово».Час від часу бажано замінити список аргументів іншим, ніж
sys.argv[1:]
, тому ви повинні читати «аргумент» як «елементsys.argv[1:]
або деяких інший список надається замістьsys.argv[1:]
».- варіант
аргумент, який використовується для надання додаткової інформації для керівництва або налаштування виконання програми. Існує багато різних синтаксисів для параметрів; традиційний синтаксис Unix - це дефіс («-«), за яким йде одна літера, напр.
-x
або-F
. Крім того, традиційний синтаксис Unix дозволяє об’єднати кілька параметрів в один аргумент, наприклад.-x -F
еквівалентно-xF
. У проекті GNU було введено--
, за яким йшов ряд слів, розділених дефісом, напр.--file
або--dry-run
. Це єдині два синтаксиси параметрів, які надаєoptparse
.Деякі інші синтаксиси параметрів, які бачив світ, включають:
дефіс, за яким слідує кілька літер, напр.
-pf
(це не те саме, що кілька параметрів, об’єднаних в один аргумент)дефіс, за яким іде ціле слово, напр.
-файл
(технічно це еквівалент попереднього синтаксису, але вони зазвичай не зустрічаються в одній програмі)знак плюс, після якого йде одна літера, або кілька літер, або слово, напр.
+f
,+rgb
косу риску, за якою йде літера, або кілька літер, або слово, напр.
/f
,/file
Ці синтаксиси параметрів не підтримуються
optparse
, і вони ніколи не будуть. Це зроблено навмисно: перші три є нестандартними для будь-якого середовища, а останній має сенс, лише якщо ви націлені виключно на Windows або певні застарілі платформи (наприклад, VMS, MS-DOS).- аргумент опції
аргумент, який слідує за опцією, тісно пов’язаний із цією опцією та споживається зі списку аргументів, коли ця опція є. З
optparse
аргументи опції можуть бути в окремому аргументі від їхньої опції:-f foo --file foo
або включено в той самий аргумент:
-ffoo --file=foo
Як правило, певна опція приймає аргумент або ні. Багатьом людям потрібна функція «необов’язкових аргументів параметрів», тобто деякі параметри прийматимуть аргумент, якщо вони його бачать, і ні, якщо вони його не бачать. Це дещо суперечливо, оскільки це робить розбір неоднозначним: якщо
-a
приймає необов’язковий аргумент, а-b
є іншим варіантом, як ми інтерпретуємо-ab
? Через цю неоднозначністьoptparse
не підтримує цю функцію.- позиційний аргумент
щось, що залишилося в списку аргументів після аналізу параметрів, тобто після аналізу параметрів і їхніх аргументів і видалення зі списку аргументів.
- необхідна опція
параметр, який необхідно вказати в командному рядку; зауважте, що фраза «необхідна опція» є суперечливою англійською мовою.
optparse
не заважає вам реалізовувати необхідні параметри, але й не дуже допомагає в цьому.
Наприклад, розглянемо цей гіпотетичний командний рядок:
prog -v --report report.txt foo bar
-v
і --report
є варіантами. Якщо припустити, що --report
приймає один аргумент, report.txt
є аргументом опції. foo
і bar
є позиційними аргументами.
Для чого існують варіанти?¶
Параметри використовуються для надання додаткової інформації для налаштування або налаштування виконання програми. Якщо це було незрозуміло, параметри зазвичай необов’язкові. Програма повинна нормально працювати без будь-яких опцій. (Виберіть випадкову програму з наборів інструментів Unix або GNU. Чи може вона запускатися взагалі без будь-яких параметрів і мати сенс? Основними винятками є find
, tar
і dd
– - усі вони є диваками-мутантами, яких справедливо критикували за нестандартний синтаксис і заплутані інтерфейси.)
Багато людей хочуть, щоб їхні програми мали «необхідні параметри». Подумай над цим. Якщо це потрібно, то це не обов’язково! Якщо є частина інформації, яка абсолютно необхідна вашій програмі для успішної роботи, це те, для чого потрібні позиційні аргументи.
Як приклад гарного дизайну інтерфейсу командного рядка розглянемо скромну утиліту cp
для копіювання файлів. Немає особливого сенсу намагатися скопіювати файли, не вказавши місце призначення та принаймні одне джерело. Отже, cp
не вдається, якщо ви запускаєте його без аргументів. Однак він має гнучкий, корисний синтаксис, який не потребує жодних опцій:
cp SOURCE DEST
cp SOURCE ... DEST-DIR
Тільки з цим можна зайти досить далеко. Більшість реалізацій cp
надають безліч параметрів для точного налаштування способу копіювання файлів: ви можете зберегти режим і час модифікації, уникати переходу за символічними посиланнями, запитувати перед тим, як затирати існуючі файли, тощо. Але це не відволікає від основної місії cp
, який скопіює або один файл до іншого, або декілька файлів до іншого каталогу.
Для чого потрібні позиційні аргументи?¶
Позиційні аргументи призначені для тих фрагментів інформації, які вашій програмі абсолютно необхідні для роботи.
Хороший інтерфейс користувача повинен мати якомога менше абсолютних вимог. Якщо ваша програма потребує 17 окремих фрагментів інформації для успішної роботи, не має великого значення як ви отримуєте цю інформацію від користувача — більшість людей здадуться та підуть, перш ніж вони успішно запустять програму. Це стосується незалежно від того, чи є інтерфейс користувача командним рядком, файлом конфігурації чи графічним інтерфейсом користувача: якщо ви поставите стільки вимог до своїх користувачів, більшість із них просто здадуться.
Коротше кажучи, намагайтеся мінімізувати кількість інформації, яку користувачі абсолютно зобов’язані надавати — використовуйте розумні значення за замовчуванням, коли це можливо. Звичайно, ви також хочете зробити свої програми досить гнучкими. Для цього і потрібні варіанти. Знову ж таки, не має значення, чи це записи у конфігураційному файлі, віджети в діалоговому вікні «Параметри» графічного інтерфейсу користувача чи параметри командного рядка — чим більше параметрів ви застосовуєте, тим гнучкішою є ваша програма, і ускладнюється його реалізація. Занадто велика гнучкість також має недоліки, звичайно; занадто багато параметрів може перевантажити користувачів і зробити ваш код набагато складнішим для підтримки.
Підручник¶
Хоча optparse
досить гнучкий і потужний, він також простий у використанні в більшості випадків. Цей розділ охоплює шаблони коду, які є спільними для будь-якої програми на основі optparse
.
По-перше, вам потрібно імпортувати клас OptionParser; потім на початку основної програми створіть екземпляр OptionParser:
from optparse import OptionParser
...
parser = OptionParser()
Потім можна приступати до визначення варіантів. Основний синтаксис:
parser.add_option(opt_str, ...,
attr=value, ...)
Кожна опція має один або більше рядків опції, наприклад -f
або --file
, і кілька атрибутів опції, які повідомляють optparse
, чого очікувати і що робити, коли він зустрічає цю опцію в командному рядку.
Як правило, кожен параметр матиме один короткий рядок параметра та один довгий рядок параметра, наприклад:
parser.add_option("-f", "--file", ...)
Ви можете визначати скільки завгодно коротких рядків параметрів і скільки завгодно довгих рядків параметрів (включаючи нуль), за умови, що є принаймні один рядок параметрів.
Рядки параметрів, передані до OptionParser.add_option()
, фактично є мітками для параметра, визначеного цим викликом. Для стислості ми будемо часто посилатися на зустріч параметра в командному рядку; насправді optparse
зустрічає рядки параметрів і шукає параметри з них.
Коли всі ваші параметри визначено, дайте команду optparse
проаналізувати командний рядок вашої програми:
(options, args) = parser.parse_args()
(If you like, you can pass a custom argument list to parse_args()
, but
that’s rarely necessary: by default it uses sys.argv[1:]
.)
parse_args()
returns two values:
options
, об’єкт, що містить значення для всіх ваших параметрів — напр. якщо--file
приймає один рядковий аргумент,options.file
буде іменем файлу, наданим користувачем, абоNone
, якщо користувач не вказав цей параметрargs
, список позиційних аргументів, що залишилися після аналізу параметрів
Цей розділ посібника охоплює лише чотири найважливіші атрибути параметрів: action
, type
, dest
(призначення) і help
. З них action
є найбільш фундаментальним.
Розуміння опціональних дій¶
Дії повідомляють optparse
, що робити, коли він зустрічає опцію в командному рядку. Існує фіксований набір дій, жорстко закодований у optparse
; додавання нових дій є розширеною темою, розглянутою в розділі Розширення optparse. Більшість дій говорять optparse
зберігати значення в деякій змінній — наприклад, взяти рядок із командного рядка та зберегти його в атрибуті options
.
Якщо ви не вкажете опцію дії, optparse
за замовчуванням буде store
.
Акція магазину¶
Найпоширенішою дією опції є store
, яка повідомляє optparse
взяти наступний аргумент (або решту поточного аргументу), переконатися, що він має правильний тип, і зберегти його у вибраному призначення.
Наприклад:
parser.add_option("-f", "--file",
action="store", type="string", dest="filename")
Тепер давайте створимо фальшивий командний рядок і попросимо optparse
розібрати його:
args = ["-f", "foo.txt"]
(options, args) = parser.parse_args(args)
When optparse
sees the option string -f
, it consumes the next
argument, foo.txt
, and stores it in options.filename
. So, after this
call to parse_args()
, options.filename
is "foo.txt"
.
Деякі інші типи опцій, які підтримує optparse
, це int
і float
. Ось варіант, який очікує цілочисельний аргумент:
parser.add_option("-n", type="int", dest="num")
Зауважте, що цей параметр не має довгого рядка параметрів, що цілком прийнятно. Крім того, немає явної дії, оскільки за замовчуванням є store
.
Давайте розберемо ще один підроблений командний рядок. Цього разу ми зіткнемося з аргументом option прямо проти параметра: оскільки -n42
(один аргумент) еквівалентний -n 42
(два аргументи), код
(options, args) = parser.parse_args(["-n42"])
print(options.num)
надрукує 42
.
Якщо ви не вкажете тип, optparse
припускає рядок
. У поєднанні з тим фактом, що типовою дією є store
, це означає, що наш перший приклад може бути набагато коротшим:
parser.add_option("-f", "--file", dest="filename")
Якщо ви не вкажете призначення, optparse
визначає розумне значення за замовчуванням із рядків параметрів: якщо перший довгий рядок параметрів – --foo-bar
, тоді призначенням за замовчуванням є foo_bar
. Якщо довгих рядків параметрів немає, optparse
шукає перший короткий рядок параметрів: типовим призначенням для -f
є f
.
optparse
також містить вбудований тип complex
. Додавання типів описано в розділі Розширення optparse.
Обробка логічних параметрів (прапорів).¶
Параметри прапорів — встановлюють для змінної значення true або false, коли відображається певний параметр — досить поширені. optparse
підтримує їх за допомогою двох окремих дій, store_true
і store_false
. Наприклад, у вас може бути прапорець verbose
, який вмикається за допомогою -v
і вимикається -q
:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")
Тут у нас є два різні варіанти з тим самим пунктом призначення, що цілком нормально. (Це лише означає, що ви повинні бути трохи обережними, встановлюючи значення за замовчуванням — див. нижче.)
Коли optparse
зустрічає -v
у командному рядку, він встановлює options.verbose
на True
; коли зустрічається -q
, options.verbose
встановлюється на False
.
Інші дії¶
Деякі інші дії, які підтримує optparse
:
"store_const"
store a constant value
"додати"
додати аргумент цього параметра до списку
"рахувати"
збільшити лічильник на одиницю
"зворотний виклик"
викликати вказану функцію
Вони описані в розділі Довідковий посібник і розділі Опція зворотних викликів.
Значення за замовчуванням¶
Усі наведені вище приклади включають встановлення деякої змінної («призначення»), коли відображаються певні параметри командного рядка. Що трапиться, якщо ці варіанти ніколи не побачать? Оскільки ми не вказали жодних значень за замовчуванням, для всіх встановлено значення None
. Зазвичай це добре, але іноді потрібно більше контролю. optparse
дозволяє вказати значення за умовчанням для кожного пункту призначення, яке призначається перед аналізом командного рядка.
Спочатку розглянемо багатослівний/тихий приклад. Якщо ми хочемо, щоб optparse
встановив для verbose
значення True
, якщо не видно -q
, ми можемо зробити це:
parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")
Оскільки значення за замовчуванням застосовуються до призначення, а не до будь-якого конкретного параметра, і ці два параметри мають одне призначення, це точно еквівалентно:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Розглянемо це:
parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Знову ж таки, значенням за замовчуванням для verbose
буде True
: останнє значення за замовчуванням, надане для будь-якого конкретного призначення, є тим, яке враховується.
A clearer way to specify default values is the set_defaults()
method of
OptionParser, which you can call at any time before calling parse_args()
:
parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()
Як і раніше, зараховується останнє значення, указане для даного призначення опції. Для ясності спробуйте використовувати один або інший метод встановлення значень за замовчуванням, а не обидва.
Створення довідки¶
Здатність optparse
автоматично генерувати текст довідки та використання корисна для створення зручних інтерфейсів командного рядка. Все, що вам потрібно зробити, це вказати значення help
для кожного параметра та, за бажанням, коротке повідомлення про використання для всієї програми. Ось OptionParser, заповнений зручними (задокументованими) параметрами:
usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=True,
help="make lots of noise [default]")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose",
help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
metavar="FILE", help="write output to FILE")
parser.add_option("-m", "--mode",
default="intermediate",
help="interaction mode: novice, intermediate, "
"or expert [default: %default]")
Якщо optparse
зустрічає -h
або --help
у командному рядку, або якщо ви просто викликаєте parser.print_help()
, він виводить наступне у стандартний вивід :
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
(Якщо вихід довідки ініціюється опцією довідки, optparse
завершує роботу після друку тексту довідки.)
Тут багато чого робиться, щоб допомогти optparse
створити найкраще довідкове повідомлення:
сценарій визначає власне повідомлення про використання:
usage = "usage: %prog [options] arg1 arg2"
optparse
розширює%prog
у рядку використання до назви поточної програми, тобтоos.path.basename(sys.argv[0])
. Потім розгорнутий рядок друкується перед детальною довідкою параметрів.Якщо ви не вказали рядок використання,
optparse
використовує м’яке, але розумне значення за умовчанням:"Використання: %prog [параметри]"
, що добре, якщо ваш сценарій не приймає жодних позиційних аргументів.кожен параметр визначає довідковий рядок і не турбується про перенесення рядків—
optparse
піклується про обтікання рядків і робить вихід довідки гарним.options that take a value indicate this fact in their automatically-generated help message, e.g. for the «mode» option:
-m MODE, --mode=MODE
Here, «MODE» is called the meta-variable: it stands for the argument that the user is expected to supply to
-m
/--mode
. By default,optparse
converts the destination variable name to uppercase and uses that for the meta-variable. Sometimes, that’s not what you want—for example, the--filename
option explicitly setsmetavar="FILE"
, resulting in this automatically-generated option description:-f FILE, --filename=FILE
Однак це важливо не тільки для економії місця: написаний вручну текст довідки використовує мета-змінну
FILE
, щоб зрозуміти користувачеві, що існує зв’язок між напівформальним синтаксисом-f FILE
і неформальний семантичний опис «записати вихід у ФАЙЛ». Це простий, але ефективний спосіб зробити ваш текст довідки набагато зрозумілішим і кориснішим для кінцевих користувачів.параметри, які мають значення за замовчуванням, можуть містити
%default
у рядку довідки —optparse
замінить його наstr()
значення параметра за замовчуванням. Якщо параметр не має значення за замовчуванням (або стандартним значенням єNone
),%default
розширюється доnone
.
Параметри групування¶
Коли ви маєте справу з багатьма параметрами, зручно згрупувати ці параметри для кращого виведення довідки. OptionParser
може містити кілька груп опцій, кожна з яких може містити кілька опцій.
Група опцій отримується за допомогою класу OptionGroup
:
-
class
optparse.
OptionGroup
(parser, title, description=None)¶ де
parser — це екземпляр
OptionParser
, до якого буде вставлено групуtitle — назва групи
description, необов’язковий, це довгий опис групи
OptionGroup
успадковує OptionContainer
(наприклад, OptionParser
), тому метод add_option()
можна використовувати для додавання опції до групи.
Після оголошення всіх опцій за допомогою методу OptionParser
add_option_group()
група додається до попередньо визначеного аналізатора.
Продовжуючи роботу з аналізатором, визначеним у попередньому розділі, додати OptionGroup
до аналізатора легко:
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
Це призведе до наступного результату довідки:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Трохи повніший приклад може включати використання кількох груп: все ще розширюючи попередній приклад:
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action="store_true",
help="Print debug information")
group.add_option("-s", "--sql", action="store_true",
help="Print all SQL statements executed")
group.add_option("-e", action="store_true", help="Print every action done")
parser.add_option_group(group)
що призводить до наступного результату:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or expert
[default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Debug Options:
-d, --debug Print debug information
-s, --sql Print all SQL statements executed
-e Print every action done
Ще один цікавий метод, зокрема під час програмної роботи з групами параметрів:
-
OptionParser.
get_option_group
(opt_str)¶ Повертає
OptionGroup
, до якої належить короткий або довгий рядок параметрів opt_str (наприклад,'-o'
або'--option'
). Якщо такоїOptionGroup
немає, повернітьNone
.
Друк рядка версії¶
Подібно до короткого рядка використання, optparse
також може надрукувати рядок версії вашої програми. Ви повинні надати рядок як аргумент version
для OptionParser:
parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
%prog
розгортається так само, як і в usage
. Окрім цього, версія
може містити все, що завгодно. Коли ви вказуєте його, optparse
автоматично додає опцію --version
до вашого аналізатора. Якщо він зустрічає цей параметр у командному рядку, він розгортає ваш рядок version
(шляхом заміни %prog
), друкує його в stdout і завершує роботу.
Наприклад, якщо ваш скрипт називається /usr/bin/foo
:
$ /usr/bin/foo --version
foo 1.0
Наступні два методи можна використати для друку та отримання рядка version
:
-
OptionParser.
print_version
(file=None)¶ Вивести повідомлення про версію для поточної програми (
self.version
) у файл (стандартний вивід за замовчуванням). Як і у випадку зprint_usage()
, будь-яке входження%prog
уself.version
замінюється назвою поточної програми. Нічого не робить, якщоself.version
порожній або невизначений.
-
OptionParser.
get_version
()¶ Те саме, що
print_version()
, але повертає рядок версії замість її друку.
Як optparse
обробляє помилки¶
Є два широких класи помилок, про які optparse
має турбуватися: помилки програміста та помилки користувача. Помилки програміста зазвичай є помилковими викликами OptionParser.add_option()
, напр. недійсні рядки опцій, невідомі атрибути опцій, відсутні атрибути опцій тощо. З цими справляються звичайним способом: викликають виняток (або optparse.OptionError
або TypeError
) і дозволяють програмі аварійно завершувати роботу.
Обробка помилок користувача є набагато важливішою, оскільки вони гарантовано траплятимуться незалежно від того, наскільки стабільним є ваш код. optparse
може автоматично виявляти деякі помилки користувача, такі як неправильні аргументи параметрів (передача -n 4x
, де -n
приймає цілочисельний аргумент), відсутні аргументи (-n
у кінець командного рядка, де -n
приймає аргумент будь-якого типу). Крім того, ви можете викликати OptionParser.error()
, щоб повідомити про помилку, визначену програмою:
(options, args) = parser.parse_args()
...
if options.a and options.b:
parser.error("options -a and -b are mutually exclusive")
У будь-якому випадку optparse
обробляє помилку однаково: він друкує повідомлення про використання програми та повідомлення про помилку до стандартної помилки та виходить зі статусом помилки 2.
Розглянемо перший приклад вище, де користувач передає 4x
опції, яка приймає ціле число:
$ /usr/bin/foo -n 4x
Usage: foo [options]
foo: error: option -n: invalid integer value: '4x'
Або, коли користувач взагалі не може передати значення:
$ /usr/bin/foo -n
Usage: foo [options]
foo: error: -n option requires an argument
optparse
-згенеровані повідомлення про помилку завжди вказують опцію, пов’язану з помилкою; обов’язково зробіть те саме під час виклику OptionParser.error()
із коду програми.
Якщо стандартна поведінка обробки помилок optparse
не відповідає вашим потребам, вам потрібно створити підклас OptionParser і перевизначити його exit()
та/або error()
методи.
Зібравши все разом¶
Ось як зазвичай виглядають сценарії на основі optparse
:
from optparse import OptionParser
...
def main():
usage = "usage: %prog [options] arg"
parser = OptionParser(usage)
parser.add_option("-f", "--file", dest="filename",
help="read data from FILENAME")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose")
...
(options, args) = parser.parse_args()
if len(args) != 1:
parser.error("incorrect number of arguments")
if options.verbose:
print("reading %s..." % options.filename)
...
if __name__ == "__main__":
main()
Довідковий посібник¶
Створення аналізатора¶
Першим кроком у використанні optparse
є створення екземпляра OptionParser.
-
class
optparse.
OptionParser
(...)¶ Конструктор OptionParser не має обов’язкових аргументів, але має декілька необов’язкових ключових аргументів. Ви завжди повинні передавати їх як аргументи ключового слова, тобто не покладайтеся на порядок, у якому оголошено аргументи.
використання
(за замовчуванням:"%prog [параметри]"
)The usage summary to print when your program is run incorrectly or with a help option. When
optparse
prints the usage string, it expands%prog
toos.path.basename(sys.argv[0])
(or toprog
if you passed that keyword argument). To suppress a usage message, pass the special valueoptparse.SUPPRESS_USAGE
.option_list
(за замовчуванням:[]
)Список об’єктів Option для заповнення аналізатора. Опції в
option_list
додаються після будь-яких опцій вstandard_option_list
(атрибут класу, який може бути встановлений підкласами OptionParser), але перед будь-якою версією або опціями довідки. Застаріле; замість цього використовуйтеadd_option()
після створення аналізатора.option_class
(за замовчуванням: optparse.Option)Клас для використання під час додавання параметрів до аналізатора в
add_option()
.version
(за замовчуванням:None
)Рядок версії для друку, коли користувач вказує параметр версії. Якщо ви вказуєте справжнє значення для
version
,optparse
автоматично додає опцію версії з єдиним рядком опції--version
. Підрядок%prog
розгортається так само, як іusage
.conflict_handler
(за замовчуванням:"помилка"
)Вказує, що робити, коли параметри з конфліктуючими рядками параметрів додаються до аналізатора; див. розділ Конфлікти між варіантами.
опис
(за замовчуванням:None
)Абзац тексту, що дає короткий огляд вашої програми.
optparse
переформатує цей абзац відповідно до поточної ширини терміналу та друкує його, коли користувач запитує допомогу (післявикористання
, але перед списком параметрів).formatter
(за замовчуванням: новийIndentedHelpFormatter
)Екземпляр optparse.HelpFormatter, який використовуватиметься для друку тексту довідки.
optparse
надає два конкретних класи для цієї мети: IndentedHelpFormatter і TitledHelpFormatter.add_help_option
(за замовчуванням:True
)Якщо істина,
optparse
додасть параметр довідки (із рядками параметрів-h
і--help
) до аналізатора.програма
Рядок для використання під час розширення
%prog
уusage
іversion
замістьos.path.basename(sys.argv[0])
.епілог
(за замовчуванням:None
)Абзац тексту довідки для друку після довідки параметра.
Заповнення аналізатора¶
Є кілька способів заповнити аналізатор параметрами. Кращим способом є використання OptionParser.add_option()
, як показано в розділі Підручник. add_option()
можна викликати одним із двох способів:
передати йому екземпляр Option (як повертає
make_option()
)передайте йому будь-яку комбінацію позиційних і ключових аргументів, які прийнятні для
make_option()
(тобто для конструктора Option), і він створить екземпляр Option для вас
Іншою альтернативою є передача списку попередньо сконструйованих екземплярів Option конструктору OptionParser, як у:
option_list = [
make_option("-f", "--filename",
action="store", type="string", dest="filename"),
make_option("-q", "--quiet",
action="store_false", dest="verbose"),
]
parser = OptionParser(option_list=option_list)
(make_option()
є фабричною функцією для створення екземплярів Option; наразі це псевдонім для конструктора Option. Майбутня версія optparse
може розділити Option на кілька класів і make_option()
вибере правильний клас для створення екземпляра. Не створюйте екземпляр Option безпосередньо.)
Визначення варіантів¶
Кожен екземпляр Option представляє набір синонімічних рядків параметрів командного рядка, напр. -f
і --file
. Ви можете вказати будь-яку кількість коротких або довгих рядків параметрів, але ви повинні вказати принаймні один загальний рядок параметрів.
Канонічним способом створення екземпляра Option
є метод add_option()
OptionParser
.
-
OptionParser.
add_option
(option)¶ -
OptionParser.
add_option
(*opt_str, attr=value, ...) Щоб визначити опцію лише за допомогою короткого рядка опції:
parser.add_option("-f", attr=value, ...)
І щоб визначити опцію лише з довгим рядком опції:
parser.add_option("--foo", attr=value, ...)
Ключові аргументи визначають атрибути нового об’єкта Option. Найважливішим атрибутом параметра є
action
, і він значною мірою визначає, які інші атрибути є доречними або необхідними. Якщо ви передаєте нерелевантні атрибути параметрів або не передаєте необхідні,optparse
викликає винятокOptionError
, пояснюючи вашу помилку.Дія параметра визначає, що робить
optparse
, коли він зустрічає цей параметр у командному рядку. Стандартні дії параметрів, жорстко закодовані вoptparse
:"магазин"
зберегти аргумент цього параметра (за замовчуванням)
"store_const"
store a constant value
"store_true"
зберігати
Правда
"store_false"
зберігати
False
"додати"
додати аргумент цього параметра до списку
"append_const"
append a constant value to a list
"рахувати"
збільшити лічильник на одиницю
"зворотний виклик"
викликати вказану функцію
"допомога"
роздрукувати повідомлення про використання, включно з усіма параметрами та документацією до них
(Якщо ви не вказали дію, за замовчуванням буде
"store"
. Для цієї дії ви також можете вказати атрибути параметрівtype
іdest
див. Стандартні опційні дії.)
As you can see, most actions involve storing or updating a value somewhere.
optparse
always creates a special object for this, conventionally called
options
(it happens to be an instance of optparse.Values
). Option
arguments (and various other values) are stored as attributes of this object,
according to the dest
(destination) option attribute.
Наприклад, коли ви дзвоните
parser.parse_args()
одна з перших речей, які робить optparse
, це створює об’єкт options
:
options = Values()
Якщо один із параметрів цього синтаксичного аналізатора визначено за допомогою
parser.add_option("-f", "--file", action="store", type="string", dest="filename")
а командний рядок, що аналізується, містить будь-яке з наступного:
-ffoo
-f foo
--file=foo
--file foo
тоді optparse
, побачивши цю опцію, зробить еквівалент:
options.filename = "foo"
Атрибути type
і dest
майже такі ж важливі, як і action
, але action
є єдиним такий, який має сенс для всіх варіантів.
Атрибути варіантів¶
Наступні атрибути параметрів можна передати як ключові аргументи до OptionParser.add_option()
. Якщо ви передаєте атрибут опції, який не має відношення до певної опції, або не передаєте потрібний атрибут опції, optparse
викликає OptionError
.
-
Option.
action
¶ (за замовчуванням:
"магазин"
)Визначає поведінку
optparse
, коли цей параметр відображається в командному рядку; доступні параметри задокументовані тут.
-
Option.
type
¶ (за замовчуванням:
"рядок"
)Тип аргументу, очікуваний цією опцією (наприклад,
"string"
або"int"
); доступні типи опцій задокументовані тут.
-
Option.
dest
¶ (за замовчуванням: отримано з рядків параметрів)
Якщо дія опції передбачає запис або зміну значення десь, це вказує
optparse
, де його писати:dest
називає атрибут об’єктаoptions
, якийoptparse
збирається, коли аналізує командний рядок.
-
Option.
default
¶ Значення для призначення цього параметра, якщо параметр не відображається в командному рядку. Дивіться також
OptionParser.set_defaults()
.
-
Option.
nargs
¶ (за замовчуванням: 1)
Скільки аргументів типу
type
має споживатися, коли відображається цей параметр. Якщо > 1,optparse
зберігатиме кортеж значень уdest
.
-
Option.
const
¶ Для дій, які зберігають постійне значення, постійне значення для збереження.
-
Option.
choices
¶ Для параметрів типу
"вибір"
, список рядків, з яких користувач може вибрати.
-
Option.
callback
¶ Для параметрів із дією
"callback"
, виклик якого потрібно викликати, коли цей параметр видно. Дивіться розділ Опція зворотних викликів для детальної інформації про аргументи, які передаються викликаному.
-
Option.
callback_args
¶ -
Option.
callback_kwargs
¶ Додаткові позиційні та ключові аргументи для передачі в
callback
після чотирьох стандартних аргументів зворотного виклику.
Стандартні опційні дії¶
Усі різні опціональні дії мають дещо різні вимоги та наслідки. Більшість дій мають кілька відповідних атрибутів параметрів, які ви можете вказати, щоб керувати поведінкою optparse
; деякі з них мають обов’язкові атрибути, які ви повинні вказати для будь-якої опції, що використовує цю дію.
"магазин"
[релевантний:type
,dest
,nargs
,choices
]За параметром має слідувати аргумент, який перетворюється на значення відповідно до
type
і зберігається вdest
. Якщоnargs
> 1, з командного рядка буде використано кілька аргументів; усе буде перетворено відповідно доtype
і збережено вdest
як кортеж. Перегляньте розділ Типи стандартних варіантів.Якщо надано
choices
(список або кортеж рядків), типом за замовчуванням є"choice"
.Якщо
type
не вказано, за замовчуванням буде"string"
.Якщо
dest
не надано,optparse
отримує призначення з першого довгого рядка параметрів (наприклад,--foo-bar
передбачаєfoo_bar
). Якщо довгих рядків параметрів немає,optparse
отримує адресат із першого короткого рядка параметрів (наприклад,-f
означаєf
).Приклад:
parser.add_option("-f") parser.add_option("-p", type="float", nargs=3, dest="point")
Під час аналізу командного рядка
-f foo.txt -p 1 -3.5 4 -fbar.txt
optparse
встановитьoptions.f = "foo.txt" options.point = (1.0, -3.5, 4.0) options.f = "bar.txt"
"store_const"
[потрібно:const
; релевантний:dest
]Значення
const
зберігається вdest
.Приклад:
parser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbose") parser.add_option("-v", "--verbose", action="store_const", const=1, dest="verbose") parser.add_option("--noisy", action="store_const", const=2, dest="verbose")
Якщо відображається
--noisy
,optparse
встановитьoptions.verbose = 2
"store_true"
[релевантний:dest
]Особливий випадок
"store_const"
, який зберігаєTrue
уdest
."store_false"
[релевантний:dest
]Подібно до
"store_true"
, але зберігаєFalse
.Приклад:
parser.add_option("--clobber", action="store_true", dest="clobber") parser.add_option("--no-clobber", action="store_false", dest="clobber")
"append"
[релевантні:type
,dest
,nargs
,choices
]За параметром має слідувати аргумент, який додається до списку в
dest
. Якщо значення за замовчуванням дляdest
не вказано, порожній список створюється автоматично, колиoptparse
вперше зустрічає цей параметр у командному рядку. Якщоnargs
> 1, споживаються кілька аргументів, а кортеж довжиниnargs
додається доdest
.Значення за замовчуванням для
type
іdest
такі самі, як і для дії"store"
.Приклад:
parser.add_option("-t", "--tracks", action="append", type="int")
Якщо в командному рядку відображається
-t3
,optparse
виконує еквівалент:options.tracks = [] options.tracks.append(int("3"))
Якщо трохи пізніше з’явиться
--tracks=4
, це так:options.tracks.append(int("4"))
Дія
append
викликає методappend
для поточного значення опції. Це означає, що будь-яке вказане значення за замовчуванням повинно мати методдодавання
. Це також означає, що якщо значення за замовчуванням не є порожнім, елементи за замовчуванням будуть присутні в розібраному значенні для параметра, а будь-які значення з командного рядка будуть додані після цих значень за замовчуванням:>>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults']) >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg']) >>> opts.files ['~/.mypkg/defaults', 'overrides.mypkg']
"append_const"
[потрібно:const
; релевантний:dest
]Як
"store_const"
, але значенняconst
додається доdest
; як і у випадку з"append"
,dest
за замовчуванням має значенняNone
, і порожній список автоматично створюється, коли вперше зустрічається опція."count"
[relevant:dest
]Збільшити ціле число, що зберігається в
dest
. Якщо значення за замовчуванням не вказано,dest
встановлюється на нуль перед першим збільшенням.Приклад:
parser.add_option("-v", action="count", dest="verbosity")
Коли
-v
з’являється в командному рядку вперше,optparse
виконує еквівалент:options.verbosity = 0 options.verbosity += 1
Кожне наступне повторення
-v
призводить до:options.verbosity += 1
"callback"
[потрібно:callback
; релевантні:type
,nargs
,callback_args
,callback_kwargs
]Виклик функції, визначеної
callback
, яка викликається якfunc(option, opt_str, value, parser, *args, **kwargs)
Дивіться розділ Опція зворотних викликів для більш детальної інформації.
"допомога"
Друкує повне довідкове повідомлення для всіх параметрів у поточному аналізаторі параметрів. Повідомлення довідки складається з рядка
usage
, переданого конструктору OptionParser, і рядкаhelp
, переданого кожному параметру.If no
help
string is supplied for an option, it will still be listed in the help message. To omit an option entirely, use the special valueoptparse.SUPPRESS_HELP
.optparse
автоматично додає опціюhelp
до всіх аналізаторів опцій, тому зазвичай вам не потрібно її створювати.Приклад:
from optparse import OptionParser, SUPPRESS_HELP # usually, a help option is added automatically, but that can # be suppressed using the add_help_option argument parser = OptionParser(add_help_option=False) parser.add_option("-h", "--help", action="help") parser.add_option("-v", action="store_true", dest="verbose", help="Be moderately verbose") parser.add_option("--file", dest="filename", help="Input file to read data from") parser.add_option("--secret", help=SUPPRESS_HELP)
Якщо
optparse
бачить або-h
, або--help
у командному рядку, він надрукує щось на кшталт наступного довідкового повідомлення до stdout (за умовиsys.argv[0]`).` є ``"foo.py"
):Usage: foo.py [options] Options: -h, --help Show this help message and exit -v Be moderately verbose --file=FILENAME Input file to read data from
Після друку довідкового повідомлення
optparse
завершує ваш процес за допомогоюsys.exit(0)
."версія"
Друкує номер версії, наданий OptionParser, у stdout і завершує роботу. Номер версії фактично форматується та друкується методом
print_version()
OptionParser. Зазвичай актуально, лише якщо аргументversion
надається конструктору OptionParser. Як і у випадку з параметрамиhelp
, ви рідко будете створювати параметриversion
, оскількиoptparse
автоматично додає їх за потреби.
Типи стандартних варіантів¶
optparse
має п’ять вбудованих типів параметрів: "string"
, "int"
, "choice"
, "float"
і "complex "
. Якщо вам потрібно додати нові типи опцій, перегляньте розділ Розширення optparse.
Аргументи параметрів рядка не перевіряються та не перетворюються жодним чином: текст у командному рядку зберігається в місці призначення (або передається зворотному виклику) як є.
Цілі аргументи (тип "int"
) аналізуються таким чином:
якщо число починається з
0x
, воно аналізується як шістнадцяткове числоякщо число починається з
0
, воно аналізується як вісімкове числоякщо число починається з
0b
, воно аналізується як двійкове числоінакше число аналізується як десяткове число
Перетворення виконується викликом int()
із відповідною основою (2, 8, 10 або 16). Якщо це не вдасться, не вийде і optparse
, хоча з більш корисним повідомленням про помилку.
Аргументи параметрів "float"
і "complex"
перетворюються безпосередньо за допомогою float()
і complex()
, з подібною обробкою помилок.
Опції "choice"
є підтипом опцій "string"
. Атрибут опції choices
(послідовність рядків) визначає набір дозволених аргументів опції. optparse.check_choice()
порівнює аргументи параметрів, надані користувачем, із цим головним списком і викликає OptionValueError
, якщо вказано недійсний рядок.
Розбір аргументів¶
The whole point of creating and populating an OptionParser is to call its
parse_args()
method:
(options, args) = parser.parse_args(args=None, values=None)
where the input parameters are
args
список аргументів для обробки (за замовчуванням:
sys.argv[1:]
)значення
an
optparse.Values
object to store option arguments in (default: a new instance ofValues
) – if you give an existing object, the option defaults will not be initialized on it
and the return values are
параметри
the same object that was passed in as
values
, or the optparse.Values instance created byoptparse
args
залишкові позиційні аргументи після обробки всіх опцій
The most common usage is to supply neither keyword argument. If you supply
values
, it will be modified with repeated setattr()
calls (roughly one
for every option argument stored to an option destination) and returned by
parse_args()
.
If parse_args()
encounters any errors in the argument list, it calls the
OptionParser’s error()
method with an appropriate end-user error message.
This ultimately terminates your process with an exit status of 2 (the
traditional Unix exit status for command-line errors).
Запити та маніпулювання вашим аналізатором параметрів¶
Поведінку аналізатора параметрів за замовчуванням можна дещо налаштувати, і ви також можете пошукати свій аналізатор параметрів і подивитися, що там є. OptionParser пропонує кілька методів, які допоможуть вам:
-
OptionParser.
disable_interspersed_args
()¶ Встановіть зупинку аналізу на першому варіанті. Наприклад, якщо
-a
і-b
є простими параметрами, які не приймають аргументів,optparse
зазвичай приймає такий синтаксис:prog -a arg1 -b arg2
і розглядає його як еквівалент
prog -a -b arg1 arg2
Щоб вимкнути цю функцію, викличте
disable_interspersed_args()
. Це відновлює традиційний синтаксис Unix, де розбір параметрів припиняється з першим аргументом, що не є параметром.Використовуйте це, якщо у вас є командний процесор, який виконує іншу команду, яка має власні параметри, і ви хочете переконатися, що ці параметри не плутаються. Наприклад, кожна команда може мати різний набір параметрів.
-
OptionParser.
enable_interspersed_args
()¶ Налаштуйте розбір так, щоб він не зупинявся на першому не-параметрі, дозволяючи вставляти перемикачі в аргументи команди. Це типова поведінка.
-
OptionParser.
get_option
(opt_str)¶ Повертає екземпляр Option із рядком параметра opt_str або
None
, якщо параметри не мають такого рядка параметра.
-
OptionParser.
has_option
(opt_str)¶ Повертає
True
, якщо OptionParser має параметр із рядком параметра opt_str (наприклад,-q
або--verbose
).
-
OptionParser.
remove_option
(opt_str)¶ Якщо
OptionParser
має параметр, що відповідає opt_str, цей параметр буде видалено. Якщо цей параметр містить будь-які інші рядки параметрів, усі ці рядки параметрів стають недійсними. Якщо opt_str не зустрічається в жодному параметрі, що належить цьомуOptionParser
, викликаєValueError
.
Конфлікти між варіантами¶
Якщо ви не будете обережні, можна легко визначити параметри з конфліктуючими рядками параметрів:
parser.add_option("-n", "--dry-run", ...)
...
parser.add_option("-n", "--noisy", ...)
(Це особливо вірно, якщо ви визначили свій власний підклас OptionParser з деякими стандартними параметрами.)
Кожного разу, коли ви додаєте опцію, optparse
перевіряє наявність конфліктів із існуючими опціями. Якщо він знайде будь-який, він викликає поточний механізм обробки конфліктів. Ви можете встановити механізм обробки конфліктів у конструкторі:
parser = OptionParser(..., conflict_handler=handler)
або окремим дзвінком:
parser.set_conflict_handler(handler)
Доступні засоби обробки конфліктів:
"помилка"
(за замовчуванням)припустити, що конфлікти параметрів є помилкою програмування, і викликати
OptionConflictError
"розв'язати"
розумно вирішувати конфлікти варіантів (див. нижче)
Як приклад, давайте визначимо OptionParser
, який розумно вирішує конфлікти, і додамо до нього конфліктуючі параметри:
parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="do no harm")
parser.add_option("-n", "--noisy", ..., help="be noisy")
At this point, optparse
detects that a previously-added option is already
using the -n
option string. Since conflict_handler
is "resolve"
,
it resolves the situation by removing -n
from the earlier option’s list of
option strings. Now --dry-run
is the only way for the user to activate
that option. If the user asks for help, the help message will reflect that:
Options:
--dry-run do no harm
...
-n, --noisy be noisy
It’s possible to whittle away the option strings for a previously-added option
until there are none left, and the user has no way of invoking that option from
the command-line. In that case, optparse
removes that option completely,
so it doesn’t show up in help text or anywhere else. Carrying on with our
existing OptionParser:
parser.add_option("--dry-run", ..., help="new dry-run option")
На цьому етапі вихідний параметр -n
/--dry-run
більше не доступний, тому optparse
видаляє його, залишаючи цей текст довідки:
Options:
...
-n, --noisy be noisy
--dry-run new dry-run option
Прибирати¶
Екземпляри OptionParser мають кілька циклічних посилань. Це не повинно бути проблемою для збирача сміття Python, але ви можете розірвати циклічні посилання явно, викликавши destroy()
на вашому OptionParser, коли ви закінчите з цим. Це особливо корисно в довготривалих програмах, де великі об’єктні графіки доступні з вашого OptionParser.
Інші методи¶
OptionParser підтримує кілька інших публічних методів:
-
OptionParser.
set_usage
(usage)¶ Set the usage string according to the rules described above for the
usage
constructor keyword argument. PassingNone
sets the default usage string; useoptparse.SUPPRESS_USAGE
to suppress a usage message.
-
OptionParser.
print_usage
(file=None)¶ Надрукувати повідомлення про використання для поточної програми (
self.usage
) у файл (стандартний вихід за замовчуванням). Будь-яке входження рядка%prog
уself.usage
замінюється назвою поточної програми. Нічого не робить, якщоself.usage
порожній або не визначений.
-
OptionParser.
get_usage
()¶ Те саме, що
print_usage()
, але повертає рядок використання замість його друку.
-
OptionParser.
set_defaults
(dest=value, ...)¶ Встановіть значення за замовчуванням для кількох пунктів призначення одночасно. Використання
set_defaults()
є кращим способом встановлення значень за замовчуванням для параметрів, оскільки кілька параметрів можуть мати одне призначення. Наприклад, якщо кілька параметрів «режиму» встановлюють одне й те саме призначення, будь-який із них може встановити значення за замовчуванням, і виграє останній:parser.add_option("--advanced", action="store_const", dest="mode", const="advanced", default="novice") # overridden below parser.add_option("--novice", action="store_const", dest="mode", const="novice", default="advanced") # overrides above setting
Щоб уникнути цієї плутанини, використовуйте
set_defaults()
:parser.set_defaults(mode="advanced") parser.add_option("--advanced", action="store_const", dest="mode", const="advanced") parser.add_option("--novice", action="store_const", dest="mode", const="novice")
Опція зворотних викликів¶
Якщо вбудованих дій і типів optparse
недостатньо для ваших потреб, у вас є два варіанти: розширити optparse
або визначити опцію зворотного виклику. Розширення optparse
є більш загальним, але надмірним для багатьох простих випадків. Досить часто простий зворотний дзвінок - це все, що вам потрібно.
Існує два кроки, щоб визначити опцію зворотного виклику:
визначте саму опцію за допомогою дії
"callback"
написати зворотний дзвінок; це функція (або метод), яка приймає щонайменше чотири аргументи, як описано нижче
Визначення опції зворотного виклику¶
Як завжди, найпростішим способом визначення опції зворотного виклику є використання методу OptionParser.add_option()
. Окрім action
, єдиним атрибутом параметра, який ви повинні вказати, є callback
, функція для виклику:
parser.add_option("-c", action="callback", callback=my_callback)
callback
є функцією (або іншим викликаним об’єктом), тому ви повинні вже визначати my_callback()
, створюючи цю опцію зворотного виклику. У цьому простому випадку optparse
навіть не знає, чи -c
приймає будь-які аргументи, що зазвичай означає, що опція не приймає аргументів — сама наявність -c
на командний рядок — це все, що йому потрібно знати. Проте за деяких обставин ви можете захотіти, щоб ваш зворотній виклик споживав довільну кількість аргументів командного рядка. Тут написання зворотних викликів стає складним; це розглянуто далі в цьому розділі.
optparse
завжди передає чотири конкретні аргументи вашому зворотному виклику, і він передасть додаткові аргументи, лише якщо ви вкажете їх через callback_args
і callback_kwargs
. Таким чином, мінімальна сигнатура функції зворотного виклику:
def my_callback(option, opt, value, parser):
Чотири аргументи зворотного виклику описані нижче.
Є кілька інших атрибутів опції, які ви можете надати, коли визначаєте опцію зворотного виклику:
type
має своє звичайне значення: як і з діями
"store"
або"append"
, воно наказуєoptparse
споживати один аргумент і перетворювати його наtype
. Замість того, щоб десь зберігати перетворені значення,optparse
передає їх вашій функції зворотного виклику.nargs
також має своє звичайне значення: якщо його надано та > 1,
optparse
споживатиме аргументиnargs
, кожен із яких має бути конвертованим уtype
. Потім він передає кортеж перетворених значень у ваш зворотній виклик.callback_args
кортеж додаткових позиційних аргументів для передачі зворотному виклику
callback_kwargs
словник додаткових ключових аргументів для передачі зворотному виклику
Як називаються зворотні виклики¶
Усі зворотні виклики викликаються наступним чином:
func(option, opt_str, value, parser, *args, **kwargs)
де
опція
це екземпляр Option, який викликає зворотний виклик
opt_str
це рядок параметрів, який можна побачити в командному рядку, який запускає зворотний виклик. (Якщо використовувався скорочений довгий параметр,
opt_str
буде повним, канонічним рядком параметра — наприклад, якщо користувач розміщує--foo
у командному рядку як скорочення для-- foobar
, тодіopt_str
буде"--foobar"
.)значення
є аргументом цього параметра в командному рядку.
optparse
очікуватиме аргумент, лише якщо встановленоtype
; типзначення
буде типом, який передбачається типом опції. Якщоtype
для цього параметра має значенняNone
(аргумент не очікується), тодіvalue
будеNone
. Якщоnargs
> 1,value
буде кортежем значень відповідного типу.парсер
це екземпляр OptionParser, який керує всім цим, головним чином корисний, оскільки ви можете отримати доступ до деяких інших цікавих даних через його атрибути екземпляра:
parser.largs
the current list of leftover arguments, ie. arguments that have been consumed but are neither options nor option arguments. Feel free to modify
parser.largs
, e.g. by adding more arguments to it. (This list will becomeargs
, the second return value ofparse_args()
.)parser.rargs
поточний список аргументів, що залишилися, тобто. з вилученими параметрами
opt_str
іvalue
(якщо застосовно), і залишаються лише наступні за ними аргументи. Не соромтеся змінитиparser.rargs
, напр. споживаючи більше аргументів.parser.values
об’єкт, де за замовчуванням зберігаються значення параметрів (екземпляр optparse.OptionValues). Це дозволяє зворотним викликам використовувати той самий механізм, що й решта
optparse
для зберігання значень параметрів; вам не потрібно возитися з глобалами чи закриттями. Ви також можете отримати доступ або змінити значення будь-яких параметрів, які вже зустрічаються в командному рядку.
args
це кортеж довільних позиційних аргументів, що надаються через атрибут опції
callback_args
.кварги
це словник довільних аргументів ключових слів, які надаються через
callback_kwargs
.
Викликання помилок у зворотному виклику¶
Функція зворотного виклику має викликати OptionValueError
, якщо є проблеми з параметром або його аргументом(ами). optparse
вловлює це та завершує програму, друкуючи повідомлення про помилку, яке ви надаєте на stderr. Ваше повідомлення має бути ясним, лаконічним, точним і вказувати на помилковий варіант. В іншому випадку користувачеві буде важко зрозуміти, що він зробив не так.
Приклад зворотного виклику 1: тривіальний зворотний виклик¶
Ось приклад опції зворотного виклику, яка не приймає аргументів і просто записує, що опцію було розглянуто:
def record_foo_seen(option, opt_str, value, parser):
parser.values.saw_foo = True
parser.add_option("--foo", action="callback", callback=record_foo_seen)
Звичайно, ви можете зробити це за допомогою дії "store_true"
.
Приклад зворотного виклику 2: перевірте порядок варіантів¶
Ось трохи цікавіший приклад: зафіксуйте факт відображення -a
, але роздуйте, якщо він стоїть після -b
у командному рядку.
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use -a after -b")
parser.values.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")
Приклад зворотного виклику 3: перевірка порядку опцій (узагальнено)¶
If you want to re-use this callback for several similar options (set a flag, but
blow up if -b
has already been seen), it needs a bit of work: the error
message and the flag that it sets must be generalized.
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use %s after -b" % opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')
Приклад зворотного виклику 4: перевірка довільної умови¶
Звичайно, ви можете поставити туди будь-яку умову — ви не обмежені перевіркою значень уже визначених параметрів. Наприклад, якщо у вас є опції, які не слід викликати в повний місяць, все, що вам потрібно зробити, це:
def check_moon(option, opt_str, value, parser):
if is_moon_full():
raise OptionValueError("%s option invalid when moon is full"
% opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("--foo",
action="callback", callback=check_moon, dest="foo")
(Визначення is_moon_full()
залишено як вправа для читача.)
Приклад зворотного виклику 5: фіксовані аргументи¶
Справи стають трохи цікавішими, коли ви визначаєте параметри зворотного виклику, які приймають фіксовану кількість аргументів. Вказівка того, що опція зворотного виклику приймає аргументи, подібна до визначення опції "store"
або "append"
: якщо ви визначаєте type
, тоді опція приймає один аргумент, який повинен бути конвертованим у цей тип; якщо ви далі визначаєте nargs
, тоді параметр приймає аргументи nargs
.
Ось приклад, який просто емулює стандартну дію "store"
:
def store_value(option, opt_str, value, parser):
setattr(parser.values, option.dest, value)
...
parser.add_option("--foo",
action="callback", callback=store_value,
type="int", nargs=3, dest="foo")
Зауважте, що optparse
піклується про споживання 3 аргументів і перетворення їх на цілі числа за вас; все, що вам потрібно зробити, це зберегти їх. (Або що завгодно; очевидно, вам не потрібен зворотний виклик для цього прикладу.)
Приклад зворотного виклику 6: змінні аргументи¶
Справи стають заплутаними, коли ви хочете, щоб параметр приймав змінну кількість аргументів. У цьому випадку ви повинні написати зворотний виклик, оскільки optparse
не надає жодних вбудованих можливостей для нього. І вам доведеться мати справу з певними тонкощами звичайного аналізу командного рядка Unix, який optparse
зазвичай обробляє для вас. Зокрема, зворотні виклики мають реалізовувати звичайні правила для голих аргументів --
і -
:
--
або-
можуть бути аргументами опціїголий
--
(якщо не аргумент для якогось параметра): зупинити обробку командного рядка та відкинути--
голий
-
(якщо не аргумент для якогось параметра): зупинити обробку командного рядка, але зберегти-
(додати його доparser.largs
)
Якщо вам потрібна опція, яка приймає змінну кількість аргументів, є кілька тонких, складних питань, про які варто потурбуватися. Точна реалізація, яку ви виберете, базуватиметься на компромісах, які ви готові зробити для своєї програми (саме тому optparse
не підтримує подібні речі напряму).
Тим не менш, ось спроба зворотного виклику для опції зі змінними аргументами:
def vararg_callback(option, opt_str, value, parser):
assert value is None
value = []
def floatable(str):
try:
float(str)
return True
except ValueError:
return False
for arg in parser.rargs:
# stop on --foo like options
if arg[:2] == "--" and len(arg) > 2:
break
# stop on -a, but not on -3 or -3.0
if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
break
value.append(arg)
del parser.rargs[:len(value)]
setattr(parser.values, option.dest, value)
...
parser.add_option("-c", "--callback", dest="vararg_attr",
action="callback", callback=vararg_callback)
Розширення optparse
¶
Оскільки двома основними факторами, що впливають на те, як optparse
інтерпретує параметри командного рядка, є дія та тип кожного параметра, найімовірнішим напрямком розширення є додавання нових дій і нових типів.
Додавання нових типів¶
Щоб додати нові типи, вам потрібно визначити власний підклас класу optparse
Option
. Цей клас має кілька атрибутів, які визначають типи optparse
: TYPES
і TYPE_CHECKER
.
-
Option.
TYPES
¶ Кортеж імен типів; у своєму підкласі просто визначте новий кортеж
TYPES
, який базується на стандартному.
-
Option.
TYPE_CHECKER
¶ Словник, що зіставляє назви типів із функціями перевірки типу. Функція перевірки типу має такий підпис:
def check_mytype(option, opt, value)
де
option
- це екземплярOption
,opt
- це рядок параметра (наприклад,-f
), аvalue
- це рядок із командного рядка, який необхідно перевірити та перетворити на потрібний тип.check_mytype()
має повертати об’єкт гіпотетичного типуmytype
. Значення, повернуте функцією перевірки типу, з’явиться в екземплярі OptionValues, поверненомуOptionParser.parse_args()
, або буде передано зворотному виклику як параметрvalue
.Ваша функція перевірки типу має викликати
OptionValueError
, якщо вона стикається з будь-якими проблемами.OptionValueError
приймає один рядковий аргумент, який передається як є до методуerror()
OptionParser
, який, у свою чергу, додає назву програми та рядок"помилка: "
і друкує все в stderr перед завершенням процесу.
Ось дурний приклад, який демонструє додавання типу параметра "complex"
для аналізу комплексних чисел у стилі Python у командному рядку. (Це ще безглуздіше, ніж було раніше, тому що optparse
1.3 додав вбудовану підтримку комплексних чисел, але нічого.)
По-перше, необхідний імпорт:
from copy import copy
from optparse import Option, OptionValueError
Спершу вам потрібно визначити свій засіб перевірки типів, оскільки на нього посилатимуться пізніше (в атрибуті класу TYPE_CHECKER
вашого підкласу Option):
def check_complex(option, opt, value):
try:
return complex(value)
except ValueError:
raise OptionValueError(
"option %s: invalid complex value: %r" % (opt, value))
Нарешті, підклас Option:
class MyOption (Option):
TYPES = Option.TYPES + ("complex",)
TYPE_CHECKER = copy(Option.TYPE_CHECKER)
TYPE_CHECKER["complex"] = check_complex
(Якби ми не зробили copy()
Option.TYPE_CHECKER
, ми б завершили зміну атрибута TYPE_CHECKER
параметра optparse
Оскільки це Python, ніщо не заважає вам це зробити, крім хороших манер і здорового глузду.)
Це воно! Тепер ви можете написати сценарій, який використовує новий тип опцій, як і будь-який інший сценарій на основі optparse
, за винятком того, що вам потрібно вказати вашому OptionParser використовувати MyOption замість Option:
parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")
Крім того, ви можете створити власний список параметрів і передати його в OptionParser; якщо ви не використовуєте add_option()
вищезгаданим способом, вам не потрібно вказувати OptionParser, який клас параметрів використовувати:
option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)
Додавання нових дій¶
Додавати нові дії трохи складніше, тому що ви повинні розуміти, що optparse
має кілька класифікацій для дій:
- дії «магазину».
дії, які призводять до того, що
optparse
зберігає значення в атрибуті поточного екземпляра OptionValues; ці параметри вимагають надання атрибутаdest
конструктору Option.- «набрані» дії
дії, які беруть значення з командного рядка та очікують, що воно буде певного типу; точніше, рядок, який можна перетворити на певний тип. Для цих параметрів потрібен атрибут
type
конструктору Option.
Це набори, що перекриваються: деякі дії «зберігання» за замовчуванням - це "store"
, "store_const"
, "append"
і "count"
, а за замовчуванням «typed» » діями є "зберігати"
, "додавати"
і "зворотний виклик"
.
Коли ви додаєте дію, вам потрібно класифікувати її, перерахувавши принаймні в одному з наступних атрибутів класу Option (усі є списками рядків):
-
Option.
ACTIONS
¶ Усі дії мають бути вказані в ACTIONS.
-
Option.
STORE_ACTIONS
¶ тут додатково перераховані дії «магазину».
-
Option.
TYPED_ACTIONS
¶ «введені» дії додатково перераховані тут.
-
Option.
ALWAYS_TYPED_ACTIONS
¶ Дії, які завжди мають тип (тобто чиї параметри завжди приймають значення), додатково перераховані тут. Єдиним ефектом цього є те, що
optparse
призначає тип за замовчуванням,"string"
, параметрам без явного типу, дія яких указана вALWAYS_TYPED_ACTIONS
.
Щоб фактично реалізувати вашу нову дію, ви повинні перевизначити метод take_action()
Option і додати регістр, який розпізнає вашу дію.
Наприклад, давайте додамо дію "розширити"
. Це схоже на стандартну дію "append"
, але замість того, щоб брати одне значення з командного рядка та додавати його до існуючого списку, "extend"
прийматиме кілька значень в одній комі -рядок із роздільниками та розширити ними існуючий список. Тобто, якщо --names
є опцією "extend"
типу "string"
, командний рядок:
--names=foo,bar --names blah --names ding,dong
призведе до списку
["foo", "bar", "blah", "ding", "dong"]
Знову ми визначаємо підклас Option:
class MyOption(Option):
ACTIONS = Option.ACTIONS + ("extend",)
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
def take_action(self, action, dest, opt, value, values, parser):
if action == "extend":
lvalue = value.split(",")
values.ensure_value(dest, []).extend(lvalue)
else:
Option.take_action(
self, action, dest, opt, value, values, parser)
Примітка.
"extend"
очікує значення в командному рядку та десь зберігає це значення, тому воно входить і вSTORE_ACTIONS
, і вTYPED_ACTIONS
.щоб гарантувати, що
optparse
призначає типовий тип"string"
діям"extend"
, ми додаємо дію"extend"
вALWAYS_TYPED_ACTIONS
також.MyOption.take_action()
реалізує лише цю нову дію та передає керування назадOption.take_action()
для стандартних дійoptparse
.values
є екземпляром класу optparse_parser.Values, який надає дуже корисний методensure_value()
.ensure_value()
це по сутіgetattr()
із запобіжним клапаном; це називається якvalues.ensure_value(attr, value)
If the
attr
attribute ofvalues
doesn’t exist or isNone
, then ensure_value() first sets it tovalue
, and then returns „value. This is very handy for actions like"extend"
,"append"
, and"count"
, all of which accumulate data in a variable and expect that variable to be of a certain type (a list for the first two, an integer for the latter). Usingensure_value()
means that scripts using your action don’t have to worry about setting a default value for the option destinations in question; they can just leave the default asNone
andensure_value()
will take care of getting it right when it’s needed.