# 16.4. `argparse` — 命令行选项、参数、子命令的解析

版本3.2中的新功能。

源代码： Lib / argparse.py

`argparse` 模块使编写用户友好的命令行界面变得更容易.程序指出了它需要的参数, 并且 `argparse`会指出参数怎样导出 `sys.argv`. 这 `argparse` 模块会自动生成帮助和使用信息和当用户给程序错误参数的时候产生的错误。

## 16.4.1. 示例

下面的python程序输入整数列表并且求和或取最大值。

    import argparse

    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('integers', metavar='N', type=int, nargs='+',
                        help='an integer for the accumulator')
    parser.add_argument('--sum', dest='accumulate', action='store_const',
                        const=sum, default=max,
                        help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print(args.accumulate(args.integers))

假设上面的Python代码保存在名为`prog.py`的文件中，它可以在命令行运行并提供有用的帮助信息：

    $ python prog.py -h
    usage: prog.py [-h] [--sum] N [N ...]

    Process some integers.

    positional arguments:
     N           an integer for the accumulator

    optional arguments:
     -h, --help  show this help message and exit
     --sum       sum the integers (default: find the max)

当使用适当的参数运行时，它会输出命令行整数的总和或最大值：

    $ python prog.py 1 2 3 4
    4

    $ python prog.py 1 2 3 4 --sum
    10

如果传入无效参数，它将发出错误：

    $ python prog.py a b c
    usage: prog.py [-h] [--sum] N [N ...]
    prog.py: error: argument N: invalid int value: 'a'

以下部分将引导您完成此示例。

### 16.4.1.1. 创建解析器

使用 `argparse` 的第一步是创建一个`ArgumentParser` 对象:

    >>> parser = argparse.ArgumentParser(description='Process some integers.')

`ArgumentParser` 对象会将命令行信息解析并保存为python需要的信息及类型

### 16.4.1.2. 添加参数

通过调用`add_argument()`方法为`ArgumentParser`添加程序参数信息.一般来说, 这些调用会告知`ArgumentParser` 如何将命令行参数转换成Python对象.这些信息将在 `parse_args()` 被调用时被存储及使用.例如：

    >>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
    ...                     help='an integer for the accumulator')
    >>> parser.add_argument('--sum', dest='accumulate', action='store_const',
    ...                     const=sum, default=max,
    ...                     help='sum the integers (default: find the max)')

之后, 调用 `parse_args()`会返回一个拥有2个属性的对象, `integers` 和`accumulate`.`integers` 属性是一个 list 包含一个或多个整数, `accumulate`属性 可能是 `sum()` 函数, 如果 `--sum`参数在命令行中有提供的话, 否则就是`max()` 函数.

### 16.4.1.3. 解析参数

`ArgumentParser`通过`parse_args()`方法解析参数。这将检查命令行，将每个参数转换为适当的类型，然后调用相应的操作。在大多数情况下，这意味着一个简单的`Namespace`对象将由从命令行解析出来的属性构建：

    >>> parser.parse_args(['--sum', '7', '-1', '42'])
    Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])

In a script, `parse_args()` will typically be called with no arguments, and the `ArgumentParser` will automatically determine the command-line arguments from `sys.argv`.

## 16.4.2. ArgumentParser对象

class `argparse.``ArgumentParser`(prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True)

  创建一个新的`ArgumentParser`对象。所有的参数都是关键字参数.以下每个参数都有其更详细的描述，但总之是：

  - prog - 程序的名字 (default: `sys.argv[0]`)
  - 用法 - 描述程序用法的字符串（默认值：从添加到解析器的参数生成）
  - description - 参数帮助前显示的文本（默认值：无）
  - epilog - 参数帮助后显示的文本（默认值：无）
  - 父母 - 其参数也应包含在内的`ArgumentParser`对象列表
  - formatter_class - 用于自定义帮助输出的类
  - prefix_chars - 可选参数前缀的字符集（默认值：' - '）
  - fromfile_prefix_chars - 前缀附加参数应读取的文件的字符集（默认值：`None`）
  - argument_default - 参数的全局默认值（默认值：`None`）
  - conflict_handler - 解决冲突选项的策略（通常不需要）
  - add_help - 为解析器添加-h / -help选项（默认值：`True`）
  - allow_abbrev - 如果缩写是明确的，允许长选项被缩写。（默认：`True`）

  版本3.5已更改： allow_abbrev参数已添加。

以下部分描述如何使用每个这些。

### 16.4.2.1. PROG

默认情况下，`ArgumentParser`对象使用`sys.argv[0]`来确定如何在帮助消息中显示程序的名称。这个默认值几乎总是可取的，因为它会使帮助消息与命令行上的程序调用方式相匹配。例如，考虑一个名为`myprogram.py`的文件，其代码如下：

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--foo', help='foo help')
    args = parser.parse_args()

该程序的帮助将显示`myprogram.py`作为程序名称（不管程序从何处被调用）：

    $ python myprogram.py --help
    usage: myprogram.py [-h] [--foo FOO]

    optional arguments:
     -h, --help  show this help message and exit
     --foo FOO   foo help
    $ cd ..
    $ python subdir\myprogram.py --help
    usage: myprogram.py [-h] [--foo FOO]

    optional arguments:
     -h, --help  show this help message and exit
     --foo FOO   foo help

To change this default behavior, another value can be supplied using the `prog=` argument to `ArgumentParser`:

    >>> parser = argparse.ArgumentParser(prog='myprogram')
    >>> parser.print_help()
    usage: myprogram [-h]

    optional arguments:
     -h, --help  show this help message and exit

请注意，无论从`sys.argv[0]`还是从`prog=`参数确定的程序名都可用于帮助使用`%(prog)s`格式说明符。

    >>> parser = argparse.ArgumentParser(prog='myprogram')
    >>> parser.add_argument('--foo', help='foo of the %(prog)s program')
    >>> parser.print_help()
    usage: myprogram [-h] [--foo FOO]

    optional arguments:
     -h, --help  show this help message and exit
     --foo FOO   foo of the myprogram program

### 16.4.2.2. usage

默认情况下，`ArgumentParser`根据它包含的参数计算使用情况消息：

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('--foo', nargs='?', help='foo help')
    >>> parser.add_argument('bar', nargs='+', help='bar help')
    >>> parser.print_help()
    usage: PROG [-h] [--foo [FOO]] bar [bar ...]

    positional arguments:
     bar          bar help

    optional arguments:
     -h, --help   show this help message and exit
     --foo [FOO]  foo help

默认消息可以用`usage=`关键字参数覆盖：

    >>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
    >>> parser.add_argument('--foo', nargs='?', help='foo help')
    >>> parser.add_argument('bar', nargs='+', help='bar help')
    >>> parser.print_help()
    usage: PROG [options]

    positional arguments:
     bar          bar help

    optional arguments:
     -h, --help   show this help message and exit
     --foo [FOO]  foo help

可以使用`%(prog)s`格式说明符在您的使用消息中填写程序名称。

### 16.4.2.3. 描述

大多数对`ArgumentParser`构造函数的调用将使用`description=`关键字参数。这个观点简要介绍了程序的功能和工作原理。在帮助消息中，说明显示在命令行用法字符串和各种参数的帮助消息之间：

    >>> parser = argparse.ArgumentParser(description='A foo that bars')
    >>> parser.print_help()
    usage: argparse.py [-h]

    A foo that bars

    optional arguments:
     -h, --help  show this help message and exit

默认情况下，描述将被行包裹，以便它符合给定的空间。要改变这种行为，请参阅formatter_class参数。

### 16.4.2.4. 结语

一些程序喜欢在参数描述之后显示程序的附加描述。这样的文本可以使用参数`epilog=`指定给`ArgumentParser`：

    >>> parser = argparse.ArgumentParser(
    ...     description='A foo that bars',
    ...     epilog="And that's how you'd foo a bar")
    >>> parser.print_help()
    usage: argparse.py [-h]

    A foo that bars

    optional arguments:
     -h, --help  show this help message and exit

    And that's how you'd foo a bar

As with the description argument, the `epilog=` text is by default line-wrapped, but this behavior can be adjusted with the formatter_class argument to `ArgumentParser`.

### 16.4.2.5. parents

有时，几个解析器共享一组通用参数。Rather than repeating the definitions of these arguments, a single parser with all the shared arguments and passed to `parents=` argument to `ArgumentParser` can be used. `parents=`参数采用`ArgumentParser`对象列表，收集所有位置和可选操作，并将这些操作添加到`ArgumentParser`对象正在构建：

    >>> parent_parser = argparse.ArgumentParser(add_help=False)
    >>> parent_parser.add_argument('--parent', type=int)

    >>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
    >>> foo_parser.add_argument('foo')
    >>> foo_parser.parse_args(['--parent', '2', 'XXX'])
    Namespace(foo='XXX', parent=2)

    >>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
    >>> bar_parser.add_argument('--bar')
    >>> bar_parser.parse_args(['--bar', 'YYY'])
    Namespace(bar='YYY', parent=None)

请注意，大多数父解析器将指定`add_help=False`。否则，`ArgumentParser`会看到两个`-h/--help`选项（一个在父节点中，另一个在子节点中）并引发一个错误。

注意

在通过`parents=`传递分析器之前，您必须完全初始化分析器。如果在子解析器之后更改父解析器，那些更改将不会反映到子解析器中。

### 16.4.2.6. formatter_class

`ArgumentParser`对象允许通过指定备用格式类来自定义帮助格式。目前，有四个这样的类：

class `argparse。` `RawDescriptionHelpFormatter`
class `argparse。` `RawTextHelpFormatter`
class `argparse。` `ArgumentDefaultsHelpFormatter`
class `argparse。` `MetavarTypeHelpFormatter`

`RawDescriptionHelpFormatter` and `RawTextHelpFormatter` give more control over how textual descriptions are displayed. 默认情况下，`ArgumentParser`对象在命令行帮助消息中包装描述和epilog文本：

    >>> parser = argparse.ArgumentParser(
    ...     prog='PROG',
    ...     description='''this description
    ...         was indented weird
    ...             but that is okay''',
    ...     epilog='''
    ...             likewise for this epilog whose whitespace will
    ...         be cleaned up and whose words will be wrapped
    ...         across a couple lines''')
    >>> parser.print_help()
    usage: PROG [-h]

    this description was indented weird but that is okay

    optional arguments:
     -h, --help  show this help message and exit

    likewise for this epilog whose whitespace will be cleaned up and whose words
    will be wrapped across a couple lines

将`RawDescriptionHelpFormatter`传递为`formatter_class=`表明描述和epilog已经被正确格式化，不应该被换行：

    >>> parser = argparse.ArgumentParser(
    ...     prog='PROG',
    ...     formatter_class=argparse.RawDescriptionHelpFormatter,
    ...     description=textwrap.dedent('''\
    ...         Please do not mess up this text!
    ...         --------------------------------
    ...             I have indented it
    ...             exactly the way
    ...             I want it
    ...         '''))
    >>> parser.print_help()
    usage: PROG [-h]

    Please do not mess up this text!
    --------------------------------
       I have indented it
       exactly the way
       I want it

    optional arguments:
     -h, --help  show this help message and exit

`RawTextHelpFormatter`为各种帮助文本保留空格，包括参数描述。

`ArgumentDefaultsHelpFormatter`自动为每个参数帮助消息添加有关默认值的信息：

    >>> parser = argparse.ArgumentParser(
    ...     prog='PROG',
    ...     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    >>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
    >>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
    >>> parser.print_help()
    usage: PROG [-h] [--foo FOO] [bar [bar ...]]

    positional arguments:
     bar         BAR! (default: [1, 2, 3])

    optional arguments:
     -h, --help  show this help message and exit
     --foo FOO   FOO! (default: 42)

`MetavarTypeHelpFormatter` uses the name of the type argument for each argument as the display name for its values (rather than using the dest as the regular formatter does):

    >>> parser = argparse.ArgumentParser(
    ...     prog='PROG',
    ...     formatter_class=argparse.MetavarTypeHelpFormatter)
    >>> parser.add_argument('--foo', type=int)
    >>> parser.add_argument('bar', type=float)
    >>> parser.print_help()
    usage: PROG [-h] [--foo int] float

    positional arguments:
      float

    optional arguments:
      -h, --help  show this help message and exit
      --foo int

### 16.4.2.7. prefix_chars

大多数命令行选项将使用`-`作为前缀，例如`-f/--foo` 需要支持不同或附加前缀字符的解析器，例如对于`+f`或`/foo`等选项，可以使用ArgumentParser构造函数的`prefix_chars=`参数指定它们：

    >>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
    >>> parser.add_argument('+f')
    >>> parser.add_argument('++bar')
    >>> parser.parse_args('+f X ++bar Y'.split())
    Namespace(bar='Y', f='X')

`prefix_chars=`参数默认为`'-'`。提供一组不包含`-`的字符将导致`-f/--foo`选项不被允许。

### 16.4.2.8. fromfile_prefix_chars

有时候，例如当处理特别长的参数列表时，将参数列表保存在文件中而不是在命令行输入它可能是有意义的。如果给`ArgumentParser`构造函数提供`fromfile_prefix_chars=`参数，那么以任何指定字符开头的参数将被视为文件，并将被参数包含。例如：

    >>> with open('args.txt', 'w') as fp:
    ...     fp.write('-f\nbar')
    >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
    >>> parser.add_argument('-f')
    >>> parser.parse_args(['-f', 'foo', '@args.txt'])
    Namespace(f='bar')

从文件中读取的参数必须默认为每行一个（但也可参见`convert_arg_line_to_args()`），并将它们视为与命令行中原始文件引用参数位于同一位置。So in the example above, the expression `['-f', 'foo', '@args.txt']` is considered equivalent to the expression `['-f', 'foo', '-f', 'bar']`.

`fromfile_prefix_chars=`参数默认为`None`，这意味着参数永远不会被视为文件引用。

### 16.4.2.9. argument_default

通常，通过将缺省值传递给`add_argument()`或通过使用特定的一组名称值对调用`set_defaults()`方法来指定参数缺省值。然而，有时候，为参数指定单个解析器范围的默认值可能很有用。这可以通过将`argument_default=`关键字参数传递给`ArgumentParser`来完成。例如，要全局禁止`parse_args()`调用上的属性创建，我们提供`argument_default=SUPPRESS`：

    >>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
    >>> parser.add_argument('--foo')
    >>> parser.add_argument('bar', nargs='?')
    >>> parser.parse_args(['--foo', '1', 'BAR'])
    Namespace(bar='BAR', foo='1')
    >>> parser.parse_args([])
    Namespace()

### 16.4.2.10. allow_abbrev

正常情况下, 当你传递参数列表给ArgumentParser的parse_args()方法时，它会自动识别出长选项的简写形式。````

将`allow_abbrev`设置为`False`即可禁用此功能：

    >>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
    >>> parser.add_argument('--foobar', action='store_true')
    >>> parser.add_argument('--foonley', action='store_false')
    >>> parser.parse_args(['--foon'])
    usage: PROG [-h] [--foobar] [--foonley]
    PROG: error: unrecognized arguments: --foon

版本3.5中的新功能。

### 16.4.2.11. conflict_handler

`ArgumentParser`对象不允许具有相同选项字符串的两个操作。默认情况下，如果尝试使用已在使用的选项字符串创建参数，则`ArgumentParser`对象会引发异常：

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-f', '--foo', help='old foo help')
    >>> parser.add_argument('--foo', help='new foo help')
    Traceback (most recent call last):
     ..
    ArgumentError: argument --foo: conflicting option string(s): --foo

有时（例如当使用父母时）使用相同的选项字符串覆盖任何较旧的参数可能会很有用。要获得这种行为，可以将`'resolve'`值提供给`ArgumentParser`的`conflict_handler=`参数：

    >>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
    >>> parser.add_argument('-f', '--foo', help='old foo help')
    >>> parser.add_argument('--foo', help='new foo help')
    >>> parser.print_help()
    usage: PROG [-h] [-f FOO] [--foo FOO]

    optional arguments:
     -h, --help  show this help message and exit
     -f FOO      old foo help
     --foo FOO   new foo help

请注意，`ArgumentParser`对象只会在所有选项字符串被覆盖的情况下移除一个操作。因此，在上面的例子中，旧的`-f/--foo`动作保留为`-f`动作，因为只有`--foo`

### 16.4.2.12. add_help

默认情况下，ArgumentParser对象添加一个选项，该选项只显示解析器的帮助消息。例如，考虑一个名为`myprogram.py`的文件，其中包含以下代码：

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--foo', help='foo help')
    args = parser.parse_args()

如果在命令行提供`-h`或`--help`，则会打印参数帮助器帮助：

    $ python myprogram.py --help
    usage: myprogram.py [-h] [--foo FOO]

    optional arguments:
     -h, --help  show this help message and exit
     --foo FOO   foo help

偶尔，禁用此帮助选项可能会有用。这可以通过将`False`作为`add_help=`参数传递给`ArgumentParser`来实现：

    >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
    >>> parser.add_argument('--foo', help='foo help')
    >>> parser.print_help()
    usage: PROG [--foo FOO]

    optional arguments:
     --foo FOO  foo help

帮助选项通常是`-h/--help`。例外情况是，如果`prefix_chars=`被指定并且不包含`-`，在这种情况下`-h`和`--help`不是有效的选项。在这种情况下，`prefix_chars`中的第一个字符用于作为帮助选项的前缀：

    >>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/')
    >>> parser.print_help()
    usage: PROG [+h]

    optional arguments:
      +h, ++help  show this help message and exit

## 16.4.3. add_argument()方法

`ArgumentParser.``add_argument`(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

  定义如何解析单个命令行参数。以下每个参数都有其更详细的描述，但总之是：

  - 名称或标志 - 可以是名称或选项字符串列表，例如 `foo`或`-f, --foo`。
  - action - 在命令行中遇到此参数时要采取的基本操作类型。
  - nargs - 应该使用的命令行参数的数量。
  - const - 某些动作和nargs选择所需的常量值。
  - 默认 - 如果参数在命令行中不存在，则生成的值。
  - type - 命令行参数应转换到的类型。
  - 选择 - 参数允许值的容器。
  - required - 是否可以省略命令行选项（仅针对可选参数）。
  - 帮助 - 参数所做的简要说明。
  - metavar - A name for the argument in usage messages.
  - dest - 要添加到由`parse_args()`返回的对象的属性的名称。

以下部分描述如何使用每个这些。

### 16.4.3.1. 名称或标志

`add_argument()`方法必须知道可选参数（如`-f`或`--foo`）或位置参数，如列表文件名，预计。传递给`add_argument()`的第一个参数必须是一系列标志或一个简单的参数名称。例如，可以创建一个可选参数，如下所示：

    >>> parser.add_argument('-f', '--foo')

而一个位置参数可以创建如下：

    >>> parser.add_argument('bar')

当调用`parse_args()`时，可选参数将由`-`前缀标识，其余参数将被假定为位置：

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-f', '--foo')
    >>> parser.add_argument('bar')
    >>> parser.parse_args(['BAR'])
    Namespace(bar='BAR', foo=None)
    >>> parser.parse_args(['BAR', '--foo', 'FOO'])
    Namespace(bar='BAR', foo='FOO')
    >>> parser.parse_args(['--foo', 'FOO'])
    usage: PROG [-h] [-f FOO] bar
    PROG: error: too few arguments

### 16.4.3.2. action

`ArgumentParser`对象将命令行参数与操作相关联。尽管大多数操作只是向由`parse_args()`返回的对象添加一个属性，但这些操作可以完成与它们相关的任何命令行参数。`action`关键字参数指定应如何处理命令行参数。提供的操作是：

- `'store'` - This just stores the argument’s value. 这是默认操作。例如：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo')
      >>> parser.parse_args('--foo 1'.split())
      Namespace(foo='1')

- `'store_const'` - 存储由const关键字参数指定的值。`'store_const'`动作最常用于指定某种标志的可选参数。例如：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', action='store_const', const=42)
      >>> parser.parse_args(['--foo'])
      Namespace(foo=42)

- `'store_true'`和`'store_false'` - 他们是 `'store_const'` 的特例,分别用于存储 `True` 和 `False`.另外，它们分别创建`False`和`True`的默认值。例如：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', action='store_true')
      >>> parser.add_argument('--bar', action='store_false')
      >>> parser.add_argument('--baz', action='store_false')
      >>> parser.parse_args('--foo --bar'.split())
      Namespace(foo=True, bar=False, baz=True)

- `'append'` - 存储一个列表，并将每个参数值附加到列表中。这对于允许多次指定选项很有用。用法示例：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', action='append')
      >>> parser.parse_args('--foo 1 --foo 2'.split())
      Namespace(foo=['1', '2'])

- `'append_const'` - 存储列表，并将const关键字参数指定的值附加到列表中。（请注意，const关键字参数默认为`None`。）当多个参数需要将常量存储到同一列表时，`'append_const'`动作通常很有用。例如：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--str', dest='types', action='append_const', const=str)
      >>> parser.add_argument('--int', dest='types', action='append_const', const=int)
      >>> parser.parse_args('--str --int'.split())
      Namespace(types=[<class 'str'>, <class 'int'>])

- `'count'` - 这会计算关键字参数发生的次数。例如，这对增加冗长级别很有用：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--verbose', '-v', action='count')
      >>> parser.parse_args(['-vvv'])
      Namespace(verbose=3)

- `'help'` - 这将显示当前解析器中所有选项的完整帮助消息，然后退出。默认情况下，帮助操作会自动添加到解析器中。有关如何创建输出的详细信息，请参阅`ArgumentParser`。

- `'version'` - 在`add_argument()`调用中需要`version=`关键字参数，并打印版本信息并在调用时退出：

      >>> import argparse
      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
      >>> parser.parse_args(['--version'])
      PROG 2.0

您也可以通过传递一个Action子类或其他实现相同接口的对象来指定一个任意的动作。推荐的方法是扩展`Action`，覆盖`__call__`方法和可选的`__init__`方法。

自定义操作的示例：

    >>> class FooAction(argparse.Action):
    ...     def __init__(self, option_strings, dest, nargs=None, **kwargs):
    ...         if nargs is not None:
    ...             raise ValueError("nargs not allowed")
    ...         super(FooAction, self).__init__(option_strings, dest, **kwargs)
    ...     def __call__(self, parser, namespace, values, option_string=None):
    ...         print('%r %r %r' % (namespace, values, option_string))
    ...         setattr(namespace, self.dest, values)
    ...
    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', action=FooAction)
    >>> parser.add_argument('bar', action=FooAction)
    >>> args = parser.parse_args('1 --foo 2'.split())
    Namespace(bar=None, foo=None) '1' None
    Namespace(bar='1', foo=None) '2' '--foo'
    >>> args
    Namespace(bar='1', foo='2')

有关更多详细信息，请参阅`Action`。

### 16.4.3.3. NARGS

ArgumentParser对象通常会将单个命令行参数与要执行的单个操作相关联。`nargs`关键字参数将不同数量的命令行参数与单个操作相关联。支持的值是：

- `N` (an integer). `N` arguments from the command line will be gathered together into a list. 例如：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', nargs=2)
      >>> parser.add_argument('bar', nargs=1)
      >>> parser.parse_args('c --foo a b'.split())
      Namespace(bar=['c'], foo=['a', 'b'])

  注意`nargs=1`生成的是一个只有一个元素的列表。这和默认的行为是不一样的，默认情况下生成的是元素自己,而不是列表。

- `'?'`如有可能，将从命令行中消耗一个参数，并将其作为单个项目生成。如果没有命令行参数，则会产生默认中的值。请注意，对于可选参数，还有一个额外的情况 - 选项字符串存在，但后面没有命令行参数。在这种情况下，将产生来自const的值。一些例子来说明这一点：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', nargs='?', const='c', default='d')
      >>> parser.add_argument('bar', nargs='?', default='d')
      >>> parser.parse_args(['XX', '--foo', 'YY'])
      Namespace(bar='XX', foo='YY')
      >>> parser.parse_args(['XX', '--foo'])
      Namespace(bar='XX', foo='c')
      >>> parser.parse_args([])
      Namespace(bar='d', foo='d')

  `nargs='?'`更常见的用途之一是允许可选的输入和输出文件：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
      ...                     default=sys.stdin)
      >>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
      ...                     default=sys.stdout)
      >>> parser.parse_args(['input.txt', 'output.txt'])
      Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>,
                outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>)
      >>> parser.parse_args([])
      Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>,
                outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)

- `'*'`所有存在的命令行参数都被收集到一个列表中。请注意，使用`nargs='*'`具有多个位置参数通常没什么意义，但可以使用具有`nargs='*'`的多个可选参数。例如：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', nargs='*')
      >>> parser.add_argument('--bar', nargs='*')
      >>> parser.add_argument('baz', nargs='*')
      >>> parser.parse_args('a b --foo x y --bar 1 2'.split())
      Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])

- `'+'`就像`'*'`一样，所有存在的命令行参数都被收集到一个列表中。此外，如果没有至少一个命令行参数，则会生成错误消息。例如：

      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> parser.add_argument('foo', nargs='+')
      >>> parser.parse_args(['a', 'b'])
      Namespace(foo=['a', 'b'])
      >>> parser.parse_args([])
      usage: PROG [-h] foo [foo ...]
      PROG: error: too few arguments

- `argparse.REMAINDER` 所有其余的命令行参数都被收集到一个列表中。这对于派发到其他命令行实用程序的命令行实用程序通常很有用：

      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> parser.add_argument('--foo')
      >>> parser.add_argument('command')
      >>> parser.add_argument('args', nargs=argparse.REMAINDER)
      >>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
      Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')

如果未提供`nargs`关键字参数，则消耗的参数数量由操作决定。通常这意味着一个命令行参数将被消耗，并且将生成单个项目（不是列表）。

### 16.4.3.4. 常量

`add_argument()`的`const`参数用于保存不从命令行读取的常量值，但是对于各种`ArgumentParser`动作。它最常见的两种用途是：

- 当使用`action='store_const'`或`action='append_const'`调用`add_argument()`时。这些操作将`const`值添加到由`parse_args()`返回的对象的其中一个属性中。示例请参阅action描述。
- 当采用可选参数(例如`-f`或者`--foo`)和采用`nargs='?'`调用`add_argument()`的时候,这会创建一个可选参数，后面跟零个或一个命令行参数。在解析命令行时，如果在后面没有命令行参数时遇到选项字符串，则会假定`const`的值。示例请参阅nargs描述。

通过`'store_const'`和`'append_const'`动作，必须给出`const`关键字参数。对于其他操作，它默认为`None`。

### 16.4.3.5. default

所有可选参数和一些位置参数可以在命令行中省略。The `default` keyword argument of `add_argument()`, whose value defaults to `None`, specifies what value should be used if the command-line argument is not present. 对于可选参数，当选项字符串不存在于命令行时，将使用`default`值：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', default=42)
    >>> parser.parse_args(['--foo', '2'])
    Namespace(foo='2')
    >>> parser.parse_args([])
    Namespace(foo=42)

如果`default`值是一个字符串，那么解析器就会将该值解析为一个命令行参数。特别是，在设置`Namespace`返回值的属性之前，解析器应用任何type转换参数（如果提供）。否则，解析器按原样使用该值：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--length', default='10', type=int)
    >>> parser.add_argument('--width', default=10.5, type=int)
    >>> parser.parse_args()
    Namespace(length=10, width=10.5)

对于nargs等于`?`的位置参数或`*`，当没有命令行参数时，使用`default`值：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('foo', nargs='?', default=42)
    >>> parser.parse_args(['a'])
    Namespace(foo='a')
    >>> parser.parse_args([])
    Namespace(foo=42)

如果命令行参数不存在，则提供`default=argparse.SUPPRESS`将导致不添加任何属性。:

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', default=argparse.SUPPRESS)
    >>> parser.parse_args([])
    Namespace()
    >>> parser.parse_args(['--foo', '1'])
    Namespace(foo='1')

### 16.4.3.6. type

默认情况下，`ArgumentParser`对象以简单的字符串读取命令行参数。但是，通常命令行字符串应该被解释为另一种类型，例如`float`或`int`。`add_argument()`的`type`关键字参数允许执行任何必需的类型检查和类型转换。常见的内置类型和函数可以直接用作`type`参数的值：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('foo', type=int)
    >>> parser.add_argument('bar', type=open)
    >>> parser.parse_args('2 temp.txt'.split())
    Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)

有关何时将`type`参数应用于缺省参数的信息，请参阅default关键字参数中的一节。

To ease the use of various types of files, the argparse module provides the factory FileType which takes the `mode=`, `bufsize=`, `encoding=` and `errors=` arguments of the `open()` function. 例如，可以使用`FileType('w')`创建可写文件：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('bar', type=argparse.FileType('w'))
    >>> parser.parse_args(['out.txt'])
    Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)

`type=`可以接受任何可接受单个字符串参数的可调用函数，并返回转换后的值：

    >>> def perfect_square(string):
    ...     value = int(string)
    ...     sqrt = math.sqrt(value)
    ...     if sqrt != int(sqrt):
    ...         msg = "%r is not a perfect square" % string
    ...         raise argparse.ArgumentTypeError(msg)
    ...     return value
    ...
    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('foo', type=perfect_square)
    >>> parser.parse_args(['9'])
    Namespace(foo=9)
    >>> parser.parse_args(['7'])
    usage: PROG [-h] foo
    PROG: error: argument foo: '7' is not a perfect square

对于类型检查器，choices关键字参数可能会更方便，它只需检查一系列值：

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('foo', type=int, choices=range(5, 10))
    >>> parser.parse_args(['7'])
    Namespace(foo=7)
    >>> parser.parse_args(['11'])
    usage: PROG [-h] {5,6,7,8,9}
    PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)

有关更多详细信息，请参阅choices部分。

### 16.4.3.7. 选择

一些命令行参数应该从一组受限制的值中选择。这些可以通过将容器对象作为choices关键字参数传递给`add_argument()`来处理。在解析命令行时，将检查参数值，如果参数不是可接受值之一，则会显示错误消息：

    >>> parser = argparse.ArgumentParser(prog='game.py')
    >>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
    >>> parser.parse_args(['rock'])
    Namespace(move='rock')
    >>> parser.parse_args(['fire'])
    usage: game.py [-h] {rock,paper,scissors}
    game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
    'paper', 'scissors')

请注意，在执行了任何类型转换后，将检查包含在choices容器中的内容，以便choices容器中的对象类型应匹配指定的类型：

    >>> parser = argparse.ArgumentParser(prog='doors.py')
    >>> parser.add_argument('door', type=int, choices=range(1, 4))
    >>> print(parser.parse_args(['3']))
    Namespace(door=3)
    >>> parser.parse_args(['4'])
    usage: doors.py [-h] {1,2,3}
    doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3)

任何的`in`运算符所支持的对象都可以作为choice的值,例如`dict`对象,`set`对象,以及自定义的容器对象.都支持。

### 16.4.3.8. required

通常，`argparse`模块假定象`-f`和`--bar`这样的标志表示可选的参数，总是在命令行中被省略。要使选项必需，可以为`required=`关键字参数指定`add_argument()`中的`True`：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', required=True)
    >>> parser.parse_args(['--foo', 'BAR'])
    Namespace(foo='BAR')
    >>> parser.parse_args([])
    usage: argparse.py [-h] [--foo FOO]
    argparse.py: error: option --foo is required

如示例所示，如果某个选项被标记为`required`，则`parse_args()`将报告错误，如果该选项不存在于命令行中。

注意

由于用户期望options为可选，所以必需的选项通常被认为是错误的形式，因此应尽可能避免。

### 16.4.3.9. 帮助

`help`值是一个包含参数简要描述的字符串。当用户请求帮助时（通常在命令行使用`-h`或`--help`），这些`help`论据：

    >>> parser = argparse.ArgumentParser(prog='frobble')
    >>> parser.add_argument('--foo', action='store_true',
    ...                     help='foo the bars before frobbling')
    >>> parser.add_argument('bar', nargs='+',
    ...                     help='one of the bars to be frobbled')
    >>> parser.parse_args(['-h'])
    usage: frobble [-h] [--foo] bar [bar ...]

    positional arguments:
     bar     one of the bars to be frobbled

    optional arguments:
     -h, --help  show this help message and exit
     --foo   foo the bars before frobbling

`help`字符串可以包含各种格式说明符以避免重复诸如程序名称或参数default之类的内容。可用的说明符包括程序名称，`%(prog)s`和大多数关于`add_argument()`的关键字参数。`%(default)s`，`%(type)s`等。:

    >>> parser = argparse.ArgumentParser(prog='frobble')
    >>> parser.add_argument('bar', nargs='?', type=int, default=42,
    ...                     help='the bar to %(prog)s (default: %(default)s)')
    >>> parser.print_help()
    usage: frobble [-h] [bar]

    positional arguments:
     bar     the bar to frobble (default: 42)

    optional arguments:
     -h, --help  show this help message and exit

由于帮助字符串支持％格式化，如果您希望文字`%`出现在帮助字符串中，您必须将其作为`%%`转义。

`argparse` supports silencing the help entry for certain options, by setting the `help` value to `argparse.SUPPRESS`:

    >>> parser = argparse.ArgumentParser(prog='frobble')
    >>> parser.add_argument('--foo', help=argparse.SUPPRESS)
    >>> parser.print_help()
    usage: frobble [-h]

    optional arguments:
      -h, --help  show this help message and exit

### 16.4.3.10. metavar

当`ArgumentParser`生成帮助消息时，它需要一些方法来引用每个期望的参数。默认情况下，ArgumentParser对象使用dest值作为每个对象的“名称”。默认情况下，对于位置参数操作，直接使用dest值，对于可选参数操作，dest值是大写的。因此，`dest='bar'`的单个位置参数将被称为`bar`。一个可选参数`--foo`应该跟随一个命令行参数，它将被称为`FOO`。一个例子：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo')
    >>> parser.add_argument('bar')
    >>> parser.parse_args('X --foo Y'.split())
    Namespace(bar='X', foo='Y')
    >>> parser.print_help()
    usage:  [-h] [--foo FOO] bar

    positional arguments:
     bar

    optional arguments:
     -h, --help  show this help message and exit
     --foo FOO

An alternative name can be specified with `metavar`:

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', metavar='YYY')
    >>> parser.add_argument('bar', metavar='XXX')
    >>> parser.parse_args('X --foo Y'.split())
    Namespace(bar='X', foo='Y')
    >>> parser.print_help()
    usage:  [-h] [--foo YYY] XXX

    positional arguments:
     XXX

    optional arguments:
     -h, --help  show this help message and exit
     --foo YYY

Note that `metavar` only changes the displayed name - the name of the attribute on the `parse_args()` object is still determined by the dest value.

`nargs`的不同值可能会导致metavar被多次使用。Providing a tuple to `metavar` specifies a different display for each of the arguments:

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-x', nargs=2)
    >>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
    >>> parser.print_help()
    usage: PROG [-h] [-x X X] [--foo bar baz]

    optional arguments:
     -h, --help     show this help message and exit
     -x X X
     --foo bar baz

### 16.4.3.11. DEST

大多数`ArgumentParser`操作都会添加一些值作为由`parse_args()`返回的对象的属性。该属性的名称由`add_argument()`的`dest`关键字参数确定。对于位置参数动作，`dest`通常作为`add_argument()`的第一个参数提供：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('bar')
    >>> parser.parse_args(['XXX'])
    Namespace(bar='XXX')

对于可选参数操作，`dest`的值通常是从选项字符串中推断出来的。`ArgumentParser`通过取第一个长选项字符串并剥离初始字符串`--`来生成`dest`的值。如果没有提供长选项字符串，则通过剥离初始的`-`字符从第一个短选项字符串中派生`dest`。任何内部的`-`字符将被转换为`_`字符以确保该字符串是有效的属性名称。下面的例子说明了这种行为：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('-f', '--foo-bar', '--foo')
    >>> parser.add_argument('-x', '-y')
    >>> parser.parse_args('-f 1 -x 2'.split())
    Namespace(foo_bar='1', x='2')
    >>> parser.parse_args('--foo 1 -y 2'.split())
    Namespace(foo_bar='1', x='2')

`dest`允许提供自定义属性名称：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', dest='bar')
    >>> parser.parse_args('--foo XXX'.split())
    Namespace(bar='XXX')

### 16.4.3.12. 动作类

Action类实现Action API，这是一个可调用的函数，它返回一个可从命令行处理参数的可调用对象。任何遵循此API的对象都可以作为`action`参数传递给`add_argument()`。

class `argparse.``Action`(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)

ArgumentParser使用Action对象来表示解析来自命令行的一个或多个字符串的单个参数所需的信息。除了`action`本身，Action类必须接受两个位置参数以及传递给`ArgumentParser.add_argument()`的所有关键字参数。

Action的实例（或任何可调用到`action`参数的返回值）应该具有属性“dest”，“option_strings”，“default”，“type”，“required”，“help”等。定义。确定这些属性的最简单方法是调用`Action.__init__`。

Action实例应该是可调用的，所以子类必须覆盖`__call__`方法，该方法应该接受四个参数：

- `parser` - 包含此操作的ArgumentParser对象。
- `namespace` - 将由`parse_args()`返回的`Namespace`对象。大多数操作都使用`setattr()`向此对象添加属性。
- `values` - 关联的命令行参数，应用了任何类型的转换。类型转换通过type关键字参数指定给`add_argument()`。
- `option_string` - 用于调用此操作的选项字符串。`option_string`参数是可选的，如果该动作与位置参数关联，则该参数将不存在。

`__call__`方法可以执行任意操作，但通常会根据`dest`和`values`在`namespace`上设置属性。

## 16.4.4. parse_args()方法

`ArgumentParser。` `parse_args` （ args = None，namespace = None ） T5>

  将参数字符串转换为对象并将它们分配为命名空间的属性。返回填充的命名空间。

  之前对`add_argument()`的调用确切地确定了哪些对象被创建以及它们如何分配。有关详细信息，请参阅`add_argument()`的文档。

  默认情况下，参数字符串取自`sys.argv`，并为属性创建一个新的空`Namespace`对象。

### 16.4.4.1. 选项值语法

`parse_args()`方法支持多种方式来指定选项的值（如果它需要一个）。在最简单的情况下，该选项及其值作为两个单独的参数传递：

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-x')
    >>> parser.add_argument('--foo')
    >>> parser.parse_args(['-x', 'X'])
    Namespace(foo=None, x='X')
    >>> parser.parse_args(['--foo', 'FOO'])
    Namespace(foo='FOO', x=None)

对于长选项（名称长于单个字符的选项），该选项和值也可以作为单个命令行参数传递，使用`=`来分隔它们：

    >>> parser.parse_args(['--foo=FOO'])
    Namespace(foo='FOO', x=None)

对于短期选项（选项只有一个字符长），选项和它的值可以连接起来：

    >>> parser.parse_args(['-xX'])
    Namespace(foo=None, x='X')

只要使用一个`-`前缀，几个简短选项就可以连接在一起，只要最后一个选项（或它们中没有一个）需要一个值：

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-x', action='store_true')
    >>> parser.add_argument('-y', action='store_true')
    >>> parser.add_argument('-z')
    >>> parser.parse_args(['-xyzZ'])
    Namespace(x=True, y=True, z='Z')

### 16.4.4.2. 无效参数

在解析命令行时，`parse_args()`检查各种错误，包括不明确的选项，无效的类型，无效的选项，错误的位置参数数量等。遇到此类错误时，它会退出并将错误与使用消息一起打印出来：

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('--foo', type=int)
    >>> parser.add_argument('bar', nargs='?')

    >>> # invalid type
    >>> parser.parse_args(['--foo', 'spam'])
    usage: PROG [-h] [--foo FOO] [bar]
    PROG: error: argument --foo: invalid int value: 'spam'

    >>> # invalid option
    >>> parser.parse_args(['--bar'])
    usage: PROG [-h] [--foo FOO] [bar]
    PROG: error: no such option: --bar

    >>> # wrong number of arguments
    >>> parser.parse_args(['spam', 'badger'])
    usage: PROG [-h] [--foo FOO] [bar]
    PROG: error: extra arguments found: badger

### 16.4.4.3. 包含`-`的参数

每当用户明确犯了错误时，`parse_args()`方法都会尝试给出错误，但是有些情况本质上是不明确的。例如，命令行参数`-1`可能是尝试指定选项或尝试提供位置参数。`parse_args()`方法在此处谨慎：如果位置参数看起来像负数，并且在解析器中没有看起来像负数的选项，则它们只能以`-`

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-x')
    >>> parser.add_argument('foo', nargs='?')

    >>> # no negative number options, so -1 is a positional argument
    >>> parser.parse_args(['-x', '-1'])
    Namespace(foo=None, x='-1')

    >>> # no negative number options, so -1 and -5 are positional arguments
    >>> parser.parse_args(['-x', '-1', '-5'])
    Namespace(foo='-5', x='-1')

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-1', dest='one')
    >>> parser.add_argument('foo', nargs='?')

    >>> # negative number options present, so -1 is an option
    >>> parser.parse_args(['-1', 'X'])
    Namespace(foo=None, one='X')

    >>> # negative number options present, so -2 is an option
    >>> parser.parse_args(['-2'])
    usage: PROG [-h] [-1 ONE] [foo]
    PROG: error: no such option: -2

    >>> # negative number options present, so both -1s are options
    >>> parser.parse_args(['-1', '-1'])
    usage: PROG [-h] [-1 ONE] [foo]
    PROG: error: argument -1: expected one argument

如果您的位置参数必须以`-`开始，而且看起来不像负数，那么可以插入伪参数`'--'`，它告诉`parse_args()`之后的所有内容都是一个位置参数：

    >>> parser.parse_args(['--', '-f'])
    Namespace(foo='-f', one=None)

### 16.4.4.4. 参数缩写（前缀匹配）

默认情况下，`parse_args()`方法by default

    >>> parser = argparse.ArgumentParser(prog='PROG')
    >>> parser.add_argument('-bacon')
    >>> parser.add_argument('-badger')
    >>> parser.parse_args('-bac MMM'.split())
    Namespace(bacon='MMM', badger=None)
    >>> parser.parse_args('-bad WOOD'.split())
    Namespace(bacon=None, badger='WOOD')
    >>> parser.parse_args('-ba BA'.split())
    usage: PROG [-h] [-bacon BACON] [-badger BADGER]
    PROG: error: ambiguous option: -ba could match -badger, -bacon

对于可能产生多个选项的参数会产生错误。通过将allow_abbrev设置为`False`，可以禁用此功能。

### 16.4.4.5. 超越`sys.argv`

有时，有一个ArgumentParser解析不同于`sys.argv`的参数可能很有用。这可以通过将字符串列表传递给`parse_args()`来完成。这对于在交互式提示下进行测试很有用：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument(
    ...     'integers', metavar='int', type=int, choices=range(10),
    ...     nargs='+', help='an integer in the range 0..9')
    >>> parser.add_argument(
    ...     '--sum', dest='accumulate', action='store_const', const=sum,
    ...     default=max, help='sum the integers (default: find the max)')
    >>> parser.parse_args(['1', '2', '3', '4'])
    Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
    >>> parser.parse_args(['1', '2', '3', '4', '--sum'])
    Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])

### 16.4.4.6. 名称空间对象

class `argparse.``Namespace`

  默认由`parse_args()`使用的简单类来创建一个拥有属性的对象并将其返回。

这个类是故意很简单的，只是一个带有可读字符串表示的`object`子类。如果您更喜欢使用类似字典的属性视图，则可以使用标准Python成语`vars()`：

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo')
    >>> args = parser.parse_args(['--foo', 'BAR'])
    >>> vars(args)
    {'foo': 'BAR'}

将`ArgumentParser`分配给已存在的对象，而不是新的`Namespace`对象可能也很有用。这可以通过指定`namespace=`关键字参数来实现：

    >>> class C:
    ...     pass
    ...
    >>> c = C()
    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo')
    >>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
    >>> c.foo
    'BAR'

## 16.4.5. 其他功能

### 16.4.5.1. 子命令

`ArgumentParser.``add_subparsers`([title][, description][, prog][, parser_class][, action][, option_string][, dest][, help][, metavar])

  Many programs split up their functionality into a number of sub-commands, for example, the `svn` program can invoke sub-commands like `svn checkout`, `svn update`, and `svn commit`. 当程序执行需要不同种类的命令行参数的几个不同功能时，以这种方式拆分功能可能是一个特别好的想法。`ArgumentParser`支持使用`add_subparsers()`方法创建这样的子命令。通常不带参数调用`add_subparsers()`方法，并返回一个特殊的操作对象。这个对象有一个方法，`add_parser()`，它接受一个命令名和任何`ArgumentParser`构造函数参数，并返回一个`ArgumentParser`照常修改。

  参数描述：

  - title - 帮助输出中的子分析器组的标题；如果提供了描述，则默认为“子命令”，否则使用标题作为位置参数
  - 描述 - 默认情况下帮助输出中的子分析器组的描述无
  - 将使用子命令帮助显示的prog - 使用信息，默认情况下程序的名称和子分析器参数前的任何位置参数
  - parser_class - 将用于创建子分析器实例的类，默认情况下是当前分析器的类（例如，ArgumentParser）
  - action - 在命令行中遇到此参数时要采取的基本操作类型
  - dest - 存储子命令名称的属性的名称；默认情况下为None并且不存储任何值
  - 帮助 - 帮助帮助输出中的子分析器组，默认为无
  - metavar - string presenting available sub-commands in help; by default it is None and presents sub-commands in form {cmd1, cmd2, ..}

  一些示例用法：

      >>> # create the top-level parser
      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> parser.add_argument('--foo', action='store_true', help='foo help')
      >>> subparsers = parser.add_subparsers(help='sub-command help')
      >>>
      >>> # create the parser for the "a" command
      >>> parser_a = subparsers.add_parser('a', help='a help')
      >>> parser_a.add_argument('bar', type=int, help='bar help')
      >>>
      >>> # create the parser for the "b" command
      >>> parser_b = subparsers.add_parser('b', help='b help')
      >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
      >>>
      >>> # parse some argument lists
      >>> parser.parse_args(['a', '12'])
      Namespace(bar=12, foo=False)
      >>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
      Namespace(baz='Z', foo=True)

  请注意，由`parse_args()`返回的对象将只包含由命令行（而不是任何其他子分析器）选择的主分析器和子分析器的属性。因此，在上面的示例中，当指定`a`命令时，仅存在`foo`和`bar`属性，并且当`b`命令被指定，只有`foo`和`baz`属性存在。

  同样，当从分析器请求帮助消息时，只会打印该特定分析器的帮助。帮助消息将不包括父解析器或同级解析器消息。（但是，可以通过向`add_parser()`提供`help=`参数来给出每个子分析器命令的帮助消息，如上所示。）

      >>> parser.parse_args(['--help'])
      usage: PROG [-h] [--foo] {a,b} ...

      positional arguments:
        {a,b}   sub-command help
          a     a help
          b     b help

      optional arguments:
        -h, --help  show this help message and exit
        --foo   foo help

      >>> parser.parse_args(['a', '--help'])
      usage: PROG a [-h] bar

      positional arguments:
        bar     bar help

      optional arguments:
        -h, --help  show this help message and exit

      >>> parser.parse_args(['b', '--help'])
      usage: PROG b [-h] [--baz {X,Y,Z}]

      optional arguments:
        -h, --help     show this help message and exit
        --baz {X,Y,Z}  baz help

  `add_subparsers()`方法也支持`title`和`description`关键字参数。当出现任何一个时，子分析器的命令将出现在帮助输出中的他们自己的组中。例如：

      >>> parser = argparse.ArgumentParser()
      >>> subparsers = parser.add_subparsers(title='subcommands',
      ...                                    description='valid subcommands',
      ...                                    help='additional help')
      >>> subparsers.add_parser('foo')
      >>> subparsers.add_parser('bar')
      >>> parser.parse_args(['-h'])
      usage:  [-h] {foo,bar} ...

      optional arguments:
        -h, --help  show this help message and exit

      subcommands:
        valid subcommands

        {foo,bar}   additional help

  此外，`add_parser`支持额外的`aliases`参数，它允许多个字符串引用相同的子分析器。举个例子,就像`svn`一样,用缩写`co`来实现`checkout`:

      >>> parser = argparse.ArgumentParser()
      >>> subparsers = parser.add_subparsers()
      >>> checkout = subparsers.add_parser('checkout', aliases=['co'])
      >>> checkout.add_argument('foo')
      >>> parser.parse_args(['co', 'bar'])
      Namespace(foo='bar')

  处理子命令的一个特别有效的方法是将`add_subparsers()`方法的使用与对`set_defaults()`的调用相结合，以便每个子分析器知道应该使用哪个Python函数执行。例如：

      >>> # sub-command functions
      >>> def foo(args):
      ...     print(args.x * args.y)
      ...
      >>> def bar(args):
      ...     print('((%s))' % args.z)
      ...
      >>> # create the top-level parser
      >>> parser = argparse.ArgumentParser()
      >>> subparsers = parser.add_subparsers()
      >>>
      >>> # create the parser for the "foo" command
      >>> parser_foo = subparsers.add_parser('foo')
      >>> parser_foo.add_argument('-x', type=int, default=1)
      >>> parser_foo.add_argument('y', type=float)
      >>> parser_foo.set_defaults(func=foo)
      >>>
      >>> # create the parser for the "bar" command
      >>> parser_bar = subparsers.add_parser('bar')
      >>> parser_bar.add_argument('z')
      >>> parser_bar.set_defaults(func=bar)
      >>>
      >>> # parse the args and call whatever function was selected
      >>> args = parser.parse_args('foo 1 -x 2'.split())
      >>> args.func(args)
      2.0
      >>>
      >>> # parse the args and call whatever function was selected
      >>> args = parser.parse_args('bar XYZYX'.split())
      >>> args.func(args)
      ((XYZYX))

  通过这种方式，可以让参数解析完成后，`parse_args()`完成调用相应函数的工作。将功能与这样的动作相关联通常是处理每个子分析器的不同动作的最简单方法。但是，如果需要检查调用的子分析器的名称，则`add_subparsers()`调用的`dest`关键字参数将起作用：

      >>> parser = argparse.ArgumentParser()
      >>> subparsers = parser.add_subparsers(dest='subparser_name')
      >>> subparser1 = subparsers.add_parser('1')
      >>> subparser1.add_argument('-x')
      >>> subparser2 = subparsers.add_parser('2')
      >>> subparser2.add_argument('y')
      >>> parser.parse_args(['2', 'frobble'])
      Namespace(subparser_name='2', y='frobble')

### 16.4.5.2. FileType对象

class `argparse.``FileType`(mode='r', bufsize=-1, encoding=None, errors=None)

  `FileType`工厂创建可传递给`ArgumentParser.add_argument()`的类型参数的对象。将`FileType`对象作为它们的类型的参数将打开命令行参数作为具有所请求模式，缓冲区大小，编码和错误处理的文件（请参阅`open()`函数更多细节）：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--raw', type=argparse.FileType('wb', 0))
      >>> parser.add_argument('out', type=argparse.FileType('w', encoding='UTF-8'))
      >>> parser.parse_args(['--raw', 'raw.dat', 'file.txt'])
      Namespace(out=<_io.TextIOWrapper name='file.txt' mode='w' encoding='UTF-8'>, raw=<_io.FileIO name='raw.dat' mode='wb'>)

  FileType对象理解伪参数`'-'`并自动将其转换为`sys.stdin`，以便读取`FileType`对象和`sys.stdout`用于写入`FileType`对象：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('infile', type=argparse.FileType('r'))
      >>> parser.parse_args(['-'])
      Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)

  版本3.4新增： 编码和错误关键字参数。

### 16.4.5.3. 参数组

`ArgumentParser.``add_argument_group`(title=None, description=None)

  默认情况下，当显示帮助消息时，`ArgumentParser`将命令行参数分组为“位置参数”和“可选参数”。如果参数的概念分组比这个默认分组更好，则可以使用`add_argument_group()`方法创建适当的分组：

      >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
      >>> group = parser.add_argument_group('group')
      >>> group.add_argument('--foo', help='foo help')
      >>> group.add_argument('bar', help='bar help')
      >>> parser.print_help()
      usage: PROG [--foo FOO] bar

      group:
        bar    bar help
        --foo FOO  foo help

  `add_argument_group()`方法返回一个参数组对象，它具有`add_argument()`方法，就像常规的`ArgumentParser`一样。当将参数添加到组中时，解析器将其视为与普通参数类似，但将参数显示在单独的组中以获取帮助消息。`add_argument_group()`方法接受可用于自定义此显示的title和description参数：

      >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
      >>> group1 = parser.add_argument_group('group1', 'group1 description')
      >>> group1.add_argument('foo', help='foo help')
      >>> group2 = parser.add_argument_group('group2', 'group2 description')
      >>> group2.add_argument('--bar', help='bar help')
      >>> parser.print_help()
      usage: PROG [--bar BAR] foo

      group1:
        group1 description

        foo    foo help

      group2:
        group2 description

        --bar BAR  bar help

  请注意，任何不在用户定义组中的参数将返回到通常的“位置参数”和“可选参数”部分。

### 16.4.5.4. 相互排斥

`ArgumentParser.``add_mutually_exclusive_group`(required=False)

  创建一个互斥组。`argparse` will make sure that only one of the arguments in the mutually exclusive group was present on the command line:

      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> group = parser.add_mutually_exclusive_group()
      >>> group.add_argument('--foo', action='store_true')
      >>> group.add_argument('--bar', action='store_false')
      >>> parser.parse_args(['--foo'])
      Namespace(bar=True, foo=True)
      >>> parser.parse_args(['--bar'])
      Namespace(bar=False, foo=False)
      >>> parser.parse_args(['--foo', '--bar'])
      usage: PROG [-h] [--foo | --bar]
      PROG: error: argument --bar: not allowed with argument --foo

  `add_mutually_exclusive_group()`方法还接受一个必需的参数，以表明至少需要一个互斥参数：

      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> group = parser.add_mutually_exclusive_group(required=True)
      >>> group.add_argument('--foo', action='store_true')
      >>> group.add_argument('--bar', action='store_false')
      >>> parser.parse_args([])
      usage: PROG [-h] (--foo | --bar)
      PROG: error: one of the arguments --foo --bar is required

  请注意，目前互斥的参数组不支持`add_argument_group()`的title和description参数。

### 16.4.5.5. 解析器默认为

`ArgumentParser.``set_defaults`(**kwargs)

  大多数情况下，通过检查命令行参数和参数操作，将完全确定由`parse_args()`返回的对象的属性。`set_defaults()`允许在没有检查命令行的情况下确定一些额外的属性：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('foo', type=int)
      >>> parser.set_defaults(bar=42, baz='badger')
      >>> parser.parse_args(['736'])
      Namespace(bar=42, baz='badger', foo=736)

  请注意，解析器级别的默认值总是覆盖参数级别的默认值：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', default='bar')
      >>> parser.set_defaults(foo='spam')
      >>> parser.parse_args([])
      Namespace(foo='spam')

  解析器级别的默认值在使用多个解析器时可能特别有用。有关此类型的示例，请参阅`add_subparsers()`方法。

`ArgumentParser.``get_default`(dest)

  获取由`add_argument()`或`set_defaults()`设置的命名空间属性的默认值：

      >>> parser = argparse.ArgumentParser()
      >>> parser.add_argument('--foo', default='badger')
      >>> parser.get_default('foo')
      'badger'

### 16.4.5.6. 打印帮助

在大多数典型应用程序中，`parse_args()`将负责格式化和打印任何使用或错误消息。但是，有几种格式化方法可用：

`ArgumentParser.``print_usage`(file=None)

  打印关于如何在命令行上调用`ArgumentParser`的简要说明。如果文件为`None`，则假定`sys.stdout`。

`ArgumentParser.``print_help`(file=None)

  打印帮助信息，包括程序使用情况以及有关使用`ArgumentParser`注册的参数的信息。如果文件为`None`，则假定`sys.stdout`。

也有这些方法的变体，只是返回一个字符串，而不是打印它：

`ArgumentParser.``format_usage`()

  返回一个字符串，其中包含应该如何在命令行上调用`ArgumentParser`的简要说明。

`ArgumentParser.``format_help`()

  返回一个包含帮助信息的字符串，包括程序使用情况和有关使用`ArgumentParser`注册的参数的信息。

### 16.4.5.7. 部分解析

`ArgumentParser.``parse_known_args`(args=None, namespace=None)

有时脚本可能只解析一些命令行参数，将剩下的参数传递给另一个脚本或程序。在这些情况下，`parse_known_args()`方法可能很有用。它的工作方式与`parse_args()`非常相似，只是在出现额外参数时不会产生错误。相反，它会返回一个包含已填充名称空间和剩余参数字符串列表的两个项目元组。

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', action='store_true')
    >>> parser.add_argument('bar')
    >>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
    (Namespace(bar='BAR', foo=True), ['--badger', 'spam'])

警告

Prefix matching规则适用于`parse_known_args()`。解析器可能会使用一个选项，即使它只是其中一个已知选项的前缀，而不是将它留在剩余的参数列表中。

### 16.4.5.8. 自定义文件解析

`ArgumentParser.``convert_arg_line_to_args`(arg_line)

  从文件读取的参数（请参阅fromfile_prefix_chars关键字参数到`ArgumentParser`构造函数）每行读取一个参数。`convert_arg_line_to_args()`可以替代发烧友阅读。

  该方法接受一个参数arg_line，它是从参数文件读取的字符串。它返回从此字符串解析的参数列表。按顺序从参数文件中读取每行一次的方法。

  这种方法的有用重写是将每个空格分隔的单词作为参数对待：

      def convert_arg_line_to_args(self, arg_line):
          return arg_line.split()

### 16.4.5.9. 退出方法

`ArgumentParser.``exit`(status=0, message=None)

  该方法终止程序，以指定的状态退出，并且如果给定，则在此之前打印消息。

`ArgumentParser.``error`(message)

  该方法将包含消息的使用消息打印到标准错误，并终止状态代码为2的程序。

## 16.4.6. 升级optparse代码

最初，`argparse`模块试图保持与`optparse`的兼容性。However, `optparse` was difficult to extend transparently, particularly with the changes required to support the new `nargs=` specifiers and better usage messages. When most everything in `optparse` had either been copy-pasted over or monkey-patched, it no longer seemed practical to try to maintain the backwards compatibility.

`argparse`模块通过多种方式改进了标准库`optparse`模块，其中包括：

- 处理位置参数。
- 支持子命令。
- 允许替代选项前缀，如`+`和`/`。
- 处理零个或多个以及一个或多个样式的参数。
- 生成更多信息的使用信息。
- 为自定义`type`和`action`提供更简单的界面。

从`optparse`到`argparse`的部分升级路径：

- 用`ArgumentParser.add_argument()`调用替换所有`optparse.OptionParser.add_option()`调用。
- Replace `(options, args) = parser.parse_args()` with `args = parser.parse_args()` and add additional `ArgumentParser.add_argument()` calls for the positional arguments. 请记住，以前称为`options`，现在在`argparse`上下文中称为`args`。
- 用`type`或`action`参数替换回调操作和`callback_*`关键字参数。
- 将`type`关键字参数的字符串名称替换为相应的类型对​​象（例如，int，float，complex等）。
- 用`Namespace`和`optparse.OptionError`和`optparse.OptionValueError`替换`optparse.Values`与`ArgumentError`
- Replace strings with implicit arguments such as `%default` or `%prog` with the standard Python syntax to use dictionaries to format strings, that is, `%(default)s` and `%(prog)s`.
- 用`调用替换OptionParser构造函数`version`参数parser.add_argument（' - version'， action ='version'， version ='＆lt； / t5> version＆gt；'）`。