Python 中的 argparse 模块使用(一)

原创

argparse 是一个 Python 命令行的解析库, 它使得 Python 编写命令行界面变得更加容易。

argparse 兼容以下的 Python 版本:

  • 2.3, 2.4, 2.5, 2.6, 2.7

  • 3.1, 3.2, 3.3, 3.4

需要注意的是低于 Python 2.7 之前的版本要单独安装后才能使用。

示例

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)

上面是官方在 2.7 版本中给出的一个例子。将上面的代码保存到 prog.py 文件内, 使用 -h 显示帮助信息:

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

执行 prog.py 并跟上合适的参数, 就会输出最大数或者累加和。

$ python prog.py 1 2 3 4
4

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

如果输入的参数当前没有设置, 那么它将给出一个错误的提示:

$ python prog.py --url http://www.example.com
usage: prog.py [-h] [--sum] N [N ...]
prog.py: error: argument N: invalid int value: 'http://www.example.com'

1.1 创建解释器

第一步使用 argparse 创建一个 ArgumentParser 对象。

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

1.2 添加参数

使用 add_argument() 方法添加参数, 当调用 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)')
>>> parser.parse_args(['--sum', '7', '-1', '42'])
Namespace(accumulate=, integers=[7, -1, 42])

上面的代码当 parser 对象调用 parse_args() 方法时, 会返回这个对象的两个属性 integersaccumulateintegers 属性返回的是一个列表(命令中使用空格分割多个参数), accumulate 属性是可以认为是一个函数的引用, python 的内建方法 summax, 如果没有指定 --sum 参数, 那么默认使用 max 方法。

1.3 ArgumentParser 对象

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)

创建一个 ArgumentParser 对象, 所有参数都应作为关键参数来设置(不设置会有默认值)。每个参数的详细说明如下:

  • prog - 程序名称 (默认: sys.argv[0])
  • usage - 描述程序的使用方法 (默认: 从添加到解析器的参数生成)
  • description - 关于程序的一段描述信息 (默认: None)
  • epilog - 帮助信息参数最底部显示的一段提示信息 (默认: None)
  • parents - 包含 ArgumentParser 对象的列表(多个 ArgumentParser 指定他们的关系)
  • formatter_class - 一个自定义帮助信息输出的类
  • prefix_chars - 命令参数的前缀符号 (默认: ‘-‘)
  • fromfile_prefix_chars - 从文件中读取前缀字符 (默认: None)
  • argument_default - 参数的全局默认值 (default: None)
  • conflict_handler - 解决冲突参数的可选项
  • add_help - 添加一个 -h/–help 参数到解释器中 (默认: True)

1.3.1 prog

在帮助信息中, ArgumentParser 对象默认使用 sys,argv[0] 来显示程序名称。这个值是必须的, 应为你需要知道这个程序是如何启动的, 如下面的例子:

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]
   ...
$ cd ../
$ python subdir/myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]
   ...

通过指定 prog 的参数来设置命令, 通常这个参数是非常有用的。如下面的代码, 就是通过 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

1.3.2 usage

默认 ArgumentParser 对象有一个 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

1.3.3 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

1.3.4 epilog

显示额外的描述信息, 例如 Example 的例子。

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

1.3.5 parents

当用多个 ArgumentParser 对象或者公共对象属性是使用, 如下面的例子 parent_parser 这里是一个公用的 ArgumentParser, 当然 parents 必须是一个列表。

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

1.3.6 formatter_class

ArgumentParser 对象允许自定义帮助信息描述的样式, 目前支持以下三种类型:

  • argparse.RawDescriptionHelpFormatter
  • argparse.RawTextHelpFormatter
  • argparse.ArgumentDefaultsHelpFormatter

下面是 ArgumentParser 对象的默认 descriptionepilog 的信息样式。

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

下面是通过 argparse.RawDescriptionHelpFormatter 来设置的风格样式。

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

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

1.3.7 prefix_chars

多数命令行使用 - 来标注关键字, 如: -f/–foo。这里可通过 prefix_chars 参数来指定关键字前缀符号, 如: +f/+foo。

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

1.3.8 fromfile_prefix_chars

当一个命令的参数非常长的时候, 我们可以把相关参数写入到一个文件中。并通过 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')

1.3.9 argument_default

当命令参数为空, 而且不想让选项使用默认参数时, 可通过 argparse.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()

1.3.10 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

有时候(例如使用 parents 的时候)简单地用相同的选项覆盖旧的选项是有用的。这里可通过 conflict_handler=resolve 达到这种效果。

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

1.3.11 add_help

是否允许当前出 -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

这里把参数的 add_help 设置为 False 后的效果。

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

– 未完待续 –