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

其中的值 你的剧本 在运行时确定(通常从 sys.argv[0]

背景

optparse 是为了鼓励使用简单的常规命令行界面创建程序而明确设计的。为此,它只支持在UNIX下常规使用的最常见的命令行语法和语义。如果您不熟悉这些约定,请阅读本节了解它们。

术语

参数

在命令行中输入并由shell传递给 execl()execv() . 在python中,参数是 sys.argv[1:] (sys.argv[0] 正在执行的程序的名称)。unix shell还使用了“word”一词。

有时可取的做法是用参数表替代 sys.argv[1:] ,因此,您应该将“argument”读作“a element of sys.argv[1:] 或作为替代物提供的其他清单 sys.argv[1:] “。

选项

用于提供额外信息以指导或自定义程序执行的参数。选项有许多不同的语法;传统的Unix语法是一个连字符(“-”)后跟一个字母,例如。 -x-F . 此外,传统的Unix语法允许将多个选项合并到单个参数中,例如 -x -F 等于 -xF . GNU项目介绍 -- 后面是一系列连字符分隔词,例如 --file--dry-run . 这是由 optparse .

世界上看到的其他一些选项语法包括:

  • 连字符后跟几个字母,例如 -pf (这是 not 与合并到单个参数中的多个选项相同)

  • 连字符后跟一个完整的单词,例如 -file (这在技术上等同于前面的语法,但它们通常不在同一程序中出现)

  • 一个加号,后跟一个字母、几个字母或一个词,例如 +f+rgb

  • 斜线后跟一个字母、几个字母或一个词的斜线。 /f/file

不支持这些选项语法 optparse 他们永远不会。这是故意的:前三个在任何环境中都是非标准的,最后一个只有在您专门针对虚拟机、MS-DOS和/或Windows时才有意义。

期权论证

跟在选项后面的参数,与该选项密切相关,并且当该选项是时从参数列表中消耗。用 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 是选项参数。 foobar 是位置参数。

有哪些选择?

选项用于提供额外的信息来优化或自定义程序的执行。如果不清楚的话,选择通常是 可选择的 . 程序应该能够正常运行,没有任何选择。(从UNIX或GNU工具集中选择一个随机程序。它能在没有任何选择的情况下运行并且仍然有意义吗?主要的例外是 findtardd ——所有这些都是突变体怪胎,因为它们的非标准语法和混淆的接口而受到了正确的批评。)

很多人希望他们的程序有“必选的选项”。想想看。如果需要,那么 不可选 !如果有一条信息是程序成功运行所绝对需要的,那么位置参数就是为了这个。

作为良好命令行界面设计的一个例子,考虑到 cp 实用程序,用于复制文件。尝试在不提供目标和至少一个源的情况下复制文件没有多大意义。因此, cp 如果不带参数运行,则失败。但是,它有一个灵活、有用的语法,根本不需要任何选项:

cp SOURCE DEST
cp SOURCE ... DEST-DIR

就这样你可以走得很远。大多数 cp 实现提供了一系列选项来精确调整文件的复制方式:您可以保留模式和修改时间,避免使用符号链接,在删除现有文件之前询问等等,但是这些都不会分散对 cp 将一个文件复制到另一个文件,或将多个文件复制到另一个目录。

什么是位置参数?

位置参数是针对那些程序绝对、积极地需要运行的信息片段的。

一个好的用户界面应该有尽可能少的绝对需求。如果你的程序需要17条不同的信息才能成功运行,那就没什么关系了。 how 你从用户那里得到信息——大多数人在成功运行程序之前都会放弃并离开。无论用户界面是命令行、配置文件还是图形用户界面,这都适用:如果您对用户提出如此多的要求,那么他们中的大多数都会放弃。

简而言之,尽量减少用户绝对需要提供的信息量——尽可能使用合理的默认值。当然,您也希望使您的程序具有相当的灵活性。这就是选择的目的。同样,不管它们是配置文件中的条目、GUI的“首选项”对话框中的小部件还是命令行选项——实现的选项越多,程序的灵活性就越高,实现的过程就越复杂。当然,太多的灵活性也有缺点;太多的选项会压倒用户,使代码更难维护。

教程

同时 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 ,解析选项后剩余的位置参数列表

本教程部分仅涵盖四个最重要的选项属性: actiontypedest (目的地),以及 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" .

支持的其他一些选项类型 optparseintfloat . 下面是一个需要整数参数的选项:

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

注意,这个选项没有长的选项字符串,这是完全可以接受的。此外,由于默认值为 store .

让我们分析另一个假命令行。这一次,我们将把选项参数直接塞进选项:因为 -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 查看第一个短选项字符串:的默认目标 -ff .

optparse 还包括内置 complex 类型。第节介绍了添加类型 延伸 optparse .

处理布尔(标志)选项

标记选项——当看到特定选项时,将变量设置为“真”或“假”,这是很常见的。 optparse 通过两个独立的动作来支持他们, store_truestore_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.verboseTrue ;当它遇到 -qoptions.verbose 设置为 False .

其他行动

支持的其他一些操作 optparse 是:

"store_const"

存储常量值

"append"

将此选项的参数附加到列表

"count"

增加一个计数器

"callback"

调用指定的函数

这些在第节中介绍 参考指南 和截面 期权回调 .

默认值

上述所有示例都涉及到在看到某些命令行选项时设置一些变量(“目的地”)。如果这些选项从未出现,会发生什么?因为我们没有提供任何默认值,所以它们都设置为 None . 这通常很好,但有时你需要更多的控制。 optparse 允许为每个目标提供默认值,该值在分析命令行之前分配。

首先,考虑详细/安静的例子。如果我们想要 optparse 设置 verboseTrue 除非 -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)

同样,默认值 verboseTrue :为任何特定目的地提供的最后一个默认值是计数的值。

指定默认值的更清晰方法是 set_defaults() OptionParser方法,可以在调用之前随时调用该方法 parse_args() ::

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

和以前一样,为给定选项目的地指定的最后一个值是计数的值。为了清晰起见,请尝试使用一种方法或另一种方法来设置默认值,而不是同时使用这两种方法。

生成帮助

optparse 自动生成帮助和使用文本的能力对于创建用户友好的命令行界面很有用。你所要做的就是提供一个 help 每个选项的值,也可以选择整个程序的简短用法消息。这里有一个选项解析器,填充了用户友好的(文档化的)选项:

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 使用温和但合理的默认值: "Usage: %prog [options]" ,如果脚本不接受任何位置参数,则可以。

  • 每个选项都定义了一个帮助字符串,并且不担心换行---optparse 注意封装行并使帮助输出看起来很好。

  • 接受值的选项在其自动生成的帮助消息中指示此事实,例如对于“模式”选项:

    -m 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 ,将其打印到stdout,然后退出。

例如,如果调用脚本 /usr/bin/foo

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

以下两种方法可用于打印和获取 version 字符串:

OptionParser.print_version(file=None)

打印当前程序的版本消息 (self.versionfile (默认标准输出)。和…一样 print_usage() ,任何发生 %prog 在里面 self.version 替换为当前程序的名称。什么都不做 self.version 为空或未定义。

OptionParser.get_version()

等同于 print_version() 但返回版本字符串而不是打印它。

怎么用? optparse 处理错误

有两大类错误 optparse 必须担心:程序员错误和用户错误。程序员错误通常是对 OptionParser.add_option() 例如,无效的选项字符串、未知的选项属性、缺少的选项属性等。这些都以通常的方式处理:引发异常(或者 optparse.OptionErrorTypeError )让程序崩溃。

处理用户错误更为重要,因为无论您的代码多么稳定,都保证会发生错误。 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构造函数没有必需的参数,但有许多可选关键字参数。您应该始终将它们作为关键字参数传递,即不要依赖于参数声明的顺序。

usage (默认: "%prog [options]"

当程序运行不正确或有帮助选项时要打印的使用率摘要。什么时候? optparse 打印使用字符串,它将展开 %progos.path.basename(sys.argv[0]) (或) prog 如果您传递了那个关键字参数)。若要禁止使用消息,请传递特殊值 optparse.SUPPRESS_USAGE .

option_list (默认: []

用于填充分析器的选项对象列表。中的选项 option_list 在中的任何选项之后添加 standard_option_list (可由OptionParser子类设置的类属性),但在任何版本或帮助选项之前。弃用;使用 add_option() 在创建解析器之后。

option_class (默认值:optparse.option)

向中的分析器添加选项时使用的类 add_option() .

version (默认: None

当用户提供版本选项时要打印的版本字符串。如果您为 versionoptparse 自动添加带有单个选项字符串的版本选项 --version . 子串 %prog 展开方式与 usage .

conflict_handler (默认: "error"

指定将具有冲突选项字符串的选项添加到分析器时要执行的操作;请参见第节 选项之间的冲突 .

description (默认: None

一段文字,简要概述你的程序。 optparse 重新格式化此段落以适应当前的终端宽度,并在用户请求帮助时打印它(在 usage ,但在选项列表之前)。

formatter (默认:一个新的 IndentedHelpFormatter

将用于打印帮助文本的optparse.helpFormatter的实例。 optparse 为此目的提供两个具体类:indentedHelpFormatter和titledHelpFormatter。

add_help_option (默认: True

如果是真的, optparse 将添加一个帮助选项(带有选项字符串 -h--help )到解析器。

prog

展开时使用的字符串 %prog 在里面 usageversion 而不是 os.path.basename(sys.argv[0]) .

epilog (默认: None

在选项“帮助”之后要打印的帮助文本段落。

填充分析器

有几种方法可以用选项填充解析器。首选的方法是 OptionParser.add_option() ,如第节所示 教程 . add_option() 可以通过以下两种方式之一调用:

  • 将选项实例传递给它(由返回 make_option()

  • 将位置参数和关键字参数的任何组合传递给 make_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() 是用于创建选项实例的factory函数;当前它是选项构造函数的别名。未来版本的 optparse 可以将选项分为几个类,并且 make_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, ...)

关键字参数定义新选项对象的属性。最重要的选项属性是 action 它在很大程度上决定了哪些其他属性是相关的或必需的。如果传递不相关的选项属性,或未能传递所需的属性, optparse 提出一个 OptionError 解释错误的例外。

选择权 行动 决定什么 optparse 在命令行上遇到此选项时执行。标准选项操作硬编码为 optparse 是:

"store"

存储此选项的参数(默认)

"store_const"

存储常量值

"store_true"

商店 True

"store_false"

商店 False

"append"

将此选项的参数附加到列表

"append_const"

将常量值附加到列表

"count"

增加一个计数器

"callback"

调用指定的函数

"help"

打印使用信息,包括所有选项及其文档

(如果不提供操作,则默认为 "store" . 对于此操作,您还可以提供 typedest 选项属性;请参见 标准选项操作

如您所见,大多数操作都涉及在某处存储或更新值。 optparse 总是为此创建一个特殊的对象,通常称为 options (它恰好是 optparse.Values )根据 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"

这个 typedest 选项属性几乎和 action ,但是 action 是唯一有意义的 all 选项。

选项属性

以下选项属性可以作为关键字参数传递给 OptionParser.add_option() . 如果传递的选项属性与特定选项无关,或者未能传递所需的选项属性, optparse 引发 OptionError .

Option.action

(default: "store")

决定 optparse 在命令行中看到此选项时的行为;可用选项将被记录。 here .

Option.type

(default: "string")

此选项所需的参数类型(例如, "string""int" );记录可用选项类型 here .

Option.dest

(默认值:从选项字符串派生)

如果选项的操作意味着在某个地方写入或修改值,这将告诉您 optparse 在哪里写: dest 命名的属性 options 对象 optparse 在分析命令行时生成。

Option.default

如果在命令行上看不到该选项,则用于该选项目标的值。也见 OptionParser.set_defaults() .

Option.nargs

(default: 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

(默认值:从选项字符串派生)

代表打印帮助文本时要使用的选项参数。见节 教程 举个例子。

标准选项操作

各种选项操作的要求和效果都略有不同。大多数操作都有几个相关的选项属性,您可以指定这些属性作为指导。 optparse 的行为;一些属性是必需的,您必须为使用该操作的任何选项指定这些属性。

  • "store" [relevant: 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" [required: const; relevant: 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" [relevant: dest]

    一个特殊的案例 "store_const" 储存 Truedest .

  • "store_false" [relevant: dest]

    喜欢 "store_true" ,但商店 False .

    例子::

    parser.add_option("--clobber", action="store_true", dest="clobber")
    parser.add_option("--no-clobber", action="store_false", dest="clobber")
    
  • "append" [relevant: type, dest, nargs, choices]

    选项后面必须跟一个参数,该参数将附加到中的列表 dest . 如果没有默认值 dest 如果提供,则在以下情况下自动创建空列表: optparse 首先在命令行上遇到这个选项。如果 nargs >1,使用多个参数,并使用一个长度为的元组 nargs 被追加到 dest .

    的默认值 typedest"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" [required: const; relevant: 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" [required: callback; relevant: 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 所有选项分析器的选项,因此通常不需要创建选项分析器。

    例子::

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

  • "version"

    将提供给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 如果给定的字符串无效。

正在分析参数

创建和填充OptionParser的关键是调用 parse_args() 方法:

(options, args) = parser.parse_args(args=None, values=None)

其中输入参数是

args

要处理的参数列表(默认: sys.argv[1:]

values

一个 optparse.Values 存储选项参数的对象(默认值:的新实例 Values )--如果给定一个现有对象,选项默认值将不会在其上初始化。

返回值为

options

传入的对象与 values 或由创建的optparse.values实例 optparse

args

处理完所有选项后剩余的位置参数

最常见的用法是不提供关键字参数。如果你提供 values ,它将被修改为重复 setattr() 调用(存储到选项目标的每个选项参数大约一个)并由返回 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()

将parsing设置为不在第一个非选项上停止,允许在开关之间插入命令参数。这是默认行为。

OptionParser.get_option(opt_str)

返回带有选项字符串的选项实例 opt_strNone 如果没有选项具有该选项字符串。

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.usagefile (默认标准输出)。字符串的任何出现 %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_argscallback_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"

value

此选项的参数是否显示在命令行上。 optparse 只有在 type 已设置;类型 value 将是选项类型所隐含的类型。如果 type 因为这个选项是 None (不需要参数),然后 valueNone . 如果 nargs >1, value 将是适当类型的值的元组。

parser

是OptionParser实例驱动了整个过程,主要是因为您可以通过它的实例属性访问其他一些有趣的数据:

parser.largs

剩余参数的当前列表,即已使用但既不是选项参数也不是选项参数的参数。请随意修改 parser.largs ,例如通过向其添加更多参数。(此列表将变为 args ,的第二个返回值 parse_args()

parser.rargs

剩余参数的当前列表,即 opt_strvalue (如果适用)删除,并且只有后面的参数仍然存在。请随意修改 parser.rargs 例如,通过使用更多的参数。

parser.values

默认情况下存储选项值的对象(optparse.option values的实例)。这使得回调使用与其他回调相同的机制 optparse 用于存储选项值;您不需要在全局或闭包中乱转。您还可以访问或修改命令行上已遇到的任何选项的值。

args

是通过 callback_args 选项属性。

kwargs

是通过提供任意关键字参数的字典 callback_kwargs .

在回调中引发错误

回调函数应引发 OptionValueError 如果选项或其参数有任何问题。 optparse 捕获此消息并终止程序,打印您提供给stderr的错误消息。您的信息应该清晰、简洁、准确,并指出错误的选项。否则,用户很难找出他们做错了什么。

回调示例1:普通回调

下面是一个不带参数的回调选项示例,它只记录看到该选项的情况:

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

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

当然,你可以用 "store_true" 行动。

回调示例2:检查选项顺序

下面是一个更有趣的例子:记录下 -a 有人看见了,但如果后面有爆炸 -b 在命令行中。::

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

回调示例3:检查选项顺序(通用)

如果要对几个类似选项重复使用此回调(设置标志,但如果 -b 已经看到了),它需要做一些工作:错误消息和它设置的标志必须被通用化。::

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

回调示例4:检查任意条件

当然,您可以在其中放置任何条件——您不局限于检查已经定义的选项的值。例如,如果你有在满月时不应该被召唤的选择,你所要做的就是:

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

(定义 is_moon_full() 留给读者作为练习。)

回调示例5:固定参数

当您定义接受固定数量参数的回调选项时,事情会变得稍微有趣一些。指定回调选项接受参数与定义 "store""append" 选项:如果定义 type ,则该选项接受一个必须可转换为该类型的参数;如果进一步定义 nargs ,然后选择 nargs 参数。

下面是一个模拟标准的例子 "store" 行动:

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

注意 optparse 注意使用3个参数,并将它们转换为整数;您所要做的就是存储它们。(或其他;显然,对于这个示例,您不需要回调。)

回调示例6:变量参数

当你想要一个选择接受一个可变数量的参数时,事情就会变得复杂起来。对于这种情况,您必须编写一个回调,作为 optparse 不提供任何内置功能。您必须处理传统的UNIX命令行解析的某些复杂问题, optparse 通常为您处理。特别是,回调应该实现传统的裸机规则 --- 参数:

  • 任何一个 --- 可以是选项参数

  • 光秃秃的 -- (如果不是某个选项的参数):停止命令行处理并放弃 --

  • 光秃秃的 - (如果不是某个选项的参数):停止命令行处理,但保留 - (附加到 parser.largs

如果你想要一个参数数目可变的选项,有几个微妙的,棘手的问题需要担心。您选择的具体实现将基于您愿意为应用程序作出的权衡(这就是为什么 optparse 不直接支持这类事情)。

不过,这里是对带有变量参数的选项的回调的一个戳:

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

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

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

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

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

延伸 optparse

既然两个主要的控制因素 optparse 解释命令行选项是每个选项的操作和类型,最可能的扩展方向是添加新操作和新类型。

添加新类型

要添加新类型,需要定义自己的子类 optparseOption 类。这个类有几个属性定义 optparse 类型: TYPESTYPE_CHECKER .

Option.TYPES

类型名的元组;在子类中,只需定义一个新的元组 TYPES 这是建立在标准的基础上的。

Option.TYPE_CHECKER

将类型名映射到类型检查函数的字典。类型检查函数具有以下签名:

def check_mytype(option, opt, value)

在哪里? option 是一个 Option 实例, opt 是选项字符串(例如, -fvalue 是命令行中必须检查并转换为所需类型的字符串。 check_mytype() 应返回假设类型的对象 mytype . 类型检查函数返回的值将出现在由返回的OptionValues实例中。 OptionParser.parse_args() 或作为 value 参数。

你的类型检查功能应该提高 OptionValueError 如果遇到任何问题。 OptionValueError 接受单个字符串参数,该参数按原样传递给 OptionParsererror() 方法,该方法依次为程序名和字符串 "error:" 并在终止进程之前将所有内容打印到stderr。

下面是一个愚蠢的示例,演示如何添加 "complex" 在命令行上解析python样式复数的选项类型。(这比以前更愚蠢,因为 optparse 1.3增加了对复数的内置支持,但没关系。)

首先,必要的输入:

from copy import copy
from optparse import Option, OptionValueError

您需要先定义类型检查器,因为稍后会提到它(在 TYPE_CHECKER 选项子类的类属性)::

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

最后,选项子类:

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 要提供给选项构造函数的属性。

“类型化”动作

从命令行中获取值并期望其为特定类型的操作;或者更确切地说,是可以转换为特定类型的字符串。这些选项需要 type 属性设置为选项构造函数。

这些是重叠集:一些默认的“存储”操作是 "store""store_const""append""count" ,而默认的“类型化”操作是 "store""append""callback" .

添加操作时,需要将其分类,方法是至少在以下选项的类属性中列出(所有都是字符串列表):

Option.ACTIONS

所有操作都必须列在操作中。

Option.STORE_ACTIONS

此处还列出了“存储”操作。

Option.TYPED_ACTIONS

此处还列出了“类型化”操作。

Option.ALWAYS_TYPED_ACTIONS

此处还列出了始终采用类型(即其选项始终采用值)的操作。唯一的效果是 optparse 指定默认类型, "string" ,到没有显式类型的选项,其操作列在 ALWAYS_TYPED_ACTIONS .

为了实际实现新操作,必须重写选项的 take_action() 方法并添加一个可识别您的操作的事例。

例如,让我们添加一个 "extend" 行动。这与标准相似 "append" 操作,但不是从命令行中获取单个值并将其附加到现有列表中, "extend" 将在一个逗号分隔的字符串中获取多个值,并用这些值扩展现有列表。也就是说,如果 --names 是一个 "extend" 类型的选项 "string" ,命令行:

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

将生成一个列表:

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

我们再次定义了选项的子类:

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

  • 以确保 optparse 指定默认类型 "string""extend" 行动,我们把 "extend" 在行动 ALWAYS_TYPED_ACTIONS 也。

  • MyOption.take_action() 只实现这一个新操作,并将控制权传递回 Option.take_action() 对于标准 optparse 行动。

  • values 是optparse_parser.values类的一个实例,它提供了非常有用的 ensure_value() 方法。 ensure_value() 本质上是 getattr() 带有安全阀;称为:

    values.ensure_value(attr, value)
    

    如果 attr 属性 values 不存在或 None ,然后确保_Value()首先将其设置为 value ,然后返回“value”。这对于像 "extend""append""count" ,所有这些变量都将数据累积到一个变量中,并期望该变量是某种类型(前两个变量的列表,后一个变量的整数)。使用 ensure_value() 意味着使用您的操作的脚本不必担心为有问题的选项目的地设置默认值;它们只需将默认值保留为 Noneensure_value() 在需要的时候会处理好的。