deepwalk源码解读1: argparse

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/github_36326955/article/details/82682521

argparse 是 Python 内置的一个用于命令项选项与参数解析的模块,通过在程序中定义好我们需要的参数,argparse 将会从 sys.argv 中解析出这些参数,并自动生成帮助和使用信息。最常用的有:

  • ArgumentParser()
  • add_argument()
  • parse_args()

这里的参数包括两种,一种是定位参数”positional arguments”,又叫做必须 参数,一种是可选参数”optional arguments”。

0. 快速上手

命令行解析包常见的有三种:”getopt”,”optparse”,”argparse”。其中”getopt”是基于C语言编写的比较古老的包,”optparse”比”getopt”更加的方便和灵活,但是自python3.2之后就不再使用,”argparse”则是在optparse模块的改进(optparse模块也是一个命令行解析哭),并且会一直使用下去。它的主要功能是:

  • 既可以处理必选参数又可以处理可选参数
  • 可以生成更好的使用信息
  • 支持子解析器的分发

下面是一个快速上手的简单例子,这个例子从命令行中读取整数然后计算累计和,并将结果写到文件中:

parser = argparse.ArgumentParser(
    description='sum the integers at the command line')
parser.add_argument(
    'integers', metavar='int', nargs='+', type=int,
    help='an integer to be summed')
parser.add_argument(
    '--log', default=sys.stdout, type=argparse.FileType('w'),
    help='the file where the sum should be written')
args = parser.parse_args()
args.log.write('%s' % sum(args.integers))
args.log.close()

关于代码的更多细节,可以继续阅读后面的小节学习。

1. 添加定位参数

请注意:argparse如果不指定类型”type”,则默认为字符串

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('your_positional_arguments', type=int, help='display an integer')
args = parser.parse_args()
print(args.your_positional_arguments)

在命令行中运行:

python ForArgumentParser.py

会给出这样的结果:

usage: ForArgumentParser.py [-h] your_positional_arguments
ForArgumentParser.py: error: the following arguments are required: your_positional_arguments

这句话告诉我们:在我们创建的parser中有一个预置的可选参数”-h”,即help,还有一个是必选参数”your_positional_arguments”,这个是我们自己添加的必选参数。

在命令行中运行

python ForArgumentParser.py -h

会给出这样的结果:

usage: ForArgumentParser.py [-h] your_positional_arguments

positional arguments:
  your_positional_arguments
                        display an integer

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

它更加详细的解释了各个参数的情况,特别的,我们看到”your_positional_arguments”这个参数对应的解释”display an integer”就是我们我们在代码中添加的句子。

在命令行中运行

python ForArgumentParser.py 32

会给出这样的结果:

32

这表明程序正确的解析了我们的命令,打印出了32。如果我们输入的不是数字而是字符呢?如

python ForArgumentParser.py adb

会给出这样的结果:

usage: ForArgumentParser.py [-h] your_positional_arguments
ForArgumentParser.py: error: argument your_positional_arguments: invalid int value: 'abc'

程序会对我们的输入做检查,这中检查是根据我们之前的语句

parser.add_argument('your_positional_arguments', type=int, help='display an integer')

进行的。

2. 添加可选参数

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("--square", help="display a square of a given number", type=int)
parser.add_argument("--cubic", help="display a cubic of a given number", type=int)

args = parser.parse_args()

if args.square:
    print args.square**2

if args.cubic:
    print args.cubic**3

输出:

$ python argparse_usage.py --h
usage: argparse_usage.py [-h] [--square SQUARE] [--cubic CUBIC]

optional arguments:
  -h, --help       show this help message and exit
  --square SQUARE  display a square of a given number
  --cubic CUBIC    display a cubic of a given number

$ python argparse_usage.py --square 8
64

$ python argparse_usage.py --cubic 8
512

$ python argparse_usage.py 8
usage: argparse_usage.py [-h] [--square SQUARE] [--cubic CUBIC]
argparse_usage.py: error: unrecognized arguments: 8

$ python argparse_usage.py  # 没有输出

3. 混合使用

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 argparse_usage.py
usage: argparse_usage.py [-h] [--sum] N [N ...]
argparse_usage.py: error: too few arguments
$ python argparse_usage.py 1 2 3 4
4
$ python argparse_usage.py 1 2 3 4 --sum
10

4. 更多的关于创建对象:ArgumentParser()

刚才我们创建对象的时候,基本上都是使用的默认即:

parser = argparse.ArgumentParser()

其实,我们还可以根据实际情况,做更加详细的初始化

5. 更多的关于添加参数:add_argument()

add_argument() 方法定义如何解析命令行参数:

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

每个参数解释如下:

5.1. name or flags

这里写参数的名字,有的时候我们希望可选参数可以是多个名字,如-h,和–help。
这个时候我们就可以写

parser.add_argument("-v", "--verbosity",type=int help="increase output verbosity")

这样在命令行中使用-v--verbosity 是一样的。

除了name or flags参数是必须之外,add_argument的其他参数都是可选参数:


5.2. action

命令行遇到参数时的动作,默认值是 store。有时候我们设定了一个可选参数,这样在命令行中就必须要有一个值的传入。例如

parser.add_argument("--verbosity",type=int help="increase output verbosity")

即便你不指定”type=int”,程序也会默认值为字符串。这段代码在命令行中需要这样运行

$ python argparetest --verbosity 32

即,这个可选参数后面必须跟一个值。我们如果打印一下help文本会发现:

$ python prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY] (请注意这里跟了一个VERBOSITY,这个是值的代称)

optional arguments:
  -h, --help            show this help message and exit
  --verbosity VERBOSITY (请注意这里跟了一个VERBOSITY,这个是值的代称,意思是--verbosity后面必须要有一个值VERBOSITY)
                        increase output verbosity

但是有时候我们定义一些可选参数,可能并不希望传值,例如可能仅仅是一个flag,这个时候我们可以这样写:

parser.add_argument("--verbose", help="increase output verbosity",
                    action="store_true")

在命令行中:

$ python argparetest --verbosity

打印一下help文本发现:

$ python prog.py --help
usage: prog.py [-h] [--verbose](请注意与上面不一样,后面没有VERBOSITY,意思是说这个可选参数不需要传值)

optional arguments:
  -h, --help  show this help message and exit
  --verbose   increase output verbosity (请注意与上面不一样,后面没有VERBOSITY,意思是说这个可选参数不需要传值)

这里使用的action="store_true" 意思是说,如果你在命令行中使用了这个参数,我就把这个参数设置为True,否则这个参数为False.


action的动作除了可以是默认的”store”,以及我们上面提到的”store_true”外, “count”: 即你每一次出现这个参数,我就计数一次存到这个参数里,例如:


import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display the square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
                    help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
    print("{}^2 == {}".format(args.square, answer))
else:
    print(answer)

试验一下:

$ python3 prog.py 4
16
$ python3 prog.py 4 -v
4^2 == 16
$ python3 prog.py 4 -vv
the square of 4 equals 16
$ python3 prog.py 4 --verbosity --verbosity
the square of 4 equals 16
$ python3 prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
$ python3 prog.py 4 -h
usage: prog.py [-h] [-v] square

positional arguments:
  square           display a square of a given number

optional arguments:
  -h, --help       show this help message and exit
  -v, --verbosity  increase output verbosity
$ python3 prog.py 4 -vvv
16

For More

‘store_const’ - This stores the value specified by the const keyword argument. The ‘store_const’ action is most commonly used with optional arguments that specify some sort of flag. For example:

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

‘store_true’ and ‘store_false’ - These are special cases of ‘store_const’ used for storing the values True and False respectively. In addition, they create default values of False and True respectively. For example:

>>> 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’ - This stores a list, and appends each argument value to the list. This is useful to allow an option to be specified multiple times. Example usage:

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

‘append_const’ - This stores a list, and appends the value specified by the const keyword argument to the list. (Note that the const keyword argument defaults to None.) The ‘append_const’ action is typically useful when multiple arguments need to store constants to the same list. For example:

>>> 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’ - This counts the number of times a keyword argument occurs. For example, this is useful for increasing verbosity levels:

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

‘help’ - This prints a complete help message for all the options in the current parser and then exits. By default a help action is automatically added to the parser. See ArgumentParser for details of how the output is created.


‘version’ - This expects a version= keyword argument in the add_argument() call, and prints version information and exits when invoked:

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

You may also specify an arbitrary action by passing an Action subclass or other object that implements the same interface. The recommended way to do this is to extend Action, overriding the call method and optionally the init method.

An example of a custom action:

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

5.3. choices

参数可允许的值的一个容器。有的时候,我们希望可选参数的值从给定的几个值中选择,例如,我可能只希望你输入0,1,2.如果你输入了3,或者其他值我不接受。这个时候可以用choices指定接受值。例如

parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="increase output verbosity")

实验一下:

$ python3 prog.py -v 3
usage: prog.py [-h] [-v {0,1,2}]
prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
$ python3 prog.py 4 -h
usage: prog.py [-h] [-v {0,1,2}]

optional arguments:
  -h, --help            show this help message and exit
  -v {0,1,2}, --verbosity {0,1,2}
                        increase output verbosity

5.4. nargs

应该读取的命令行参数个数,可以是:
整数,”?”号,”*” 号,”+” 号, argparse.REMAINDER

nargs取整数时

parser.add_argument(
    '-integers', metavar='int', nargs=2, type=int,
    help='display integers')
args = parser.parse_args()
print(args)

输出:

$ python ForArgumentParser.py -integers 1 2
Namespace(integers=[1, 2])

nargs取’?’时

先看一个例子

import argparse

parser = argparse.ArgumentParser(
    description='sum the integers at the command line')
parser.add_argument('--foo', nargs='?', const='appear_use_this_common_without_value',default='appear_donnot_use_this_common')
args = parser.parse_args('--foo'.split())
print(args)

args = parser.parse_args(''.split())
print(args)

结果:

Namespace(foo='appear_use_this_common_without_value')
Namespace(foo='appear_donnot_use_this_common')

从中可以看出,nargs=’?’时:
1. 仅对于可选参数: 如果你在命令行里使用了该命令参数,但是没有为这个参数赋值,那么这个参数将使用const里的值。
2. 对于可选参数和位置参数: 如果你在命令行里使用了该命令参数,并且为这个参数赋值,那么这个参数将使用你赋的值。
3. 对于可选参数和位置参数: 如果你在命令行里你没有使用了该命令参数,那么这个参数将使用default里的值。如果这个时候你没有设定default,那么此时输出的结果是Namespace(foo=None)

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取’*’时

All command-line arguments present are gathered into a list. Note that it generally doesn’t make much sense to have more than one positional argument with nargs=’*’, but multiple optional arguments with nargs=’*’ is possible. For example:

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

nargs取’+’时
Just like ‘*’, all command-line args present are gathered into a list. Additionally, an error message will be generated if there wasn’t at least one command-line argument present. For example:

>>> 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: the following arguments are required: foo

nargs取argparse.REMAINDER时
All the remaining command-line arguments are gathered into a list. This is commonly useful for command line utilities that dispatch to other command line utilities:

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

5.5. 其他比较简单的参数

default: 用add_argument()添加参数时指定的默认值
type: 命令行参数应该被转换成的类型。很简单不再赘述。需要说明的是,可转换的类型有:
required: 可选参数是否可以省略 (仅针对可选参数)。True or False
help: 参数的帮助信息,当指定为 argparse.SUPPRESS 时表示不显示该参数的帮助信息.
metavar: 在usage说明中的参数名称,对于必选参数默认就是参数名称,对于可选参数默认是全大写的参数名称.
dest: 解析后的参数名称,默认情况下,对于可选参数选取最长的名称,中划线转换为下划线.
store_const: 表示赋值为const;
append: 将遇到的值存储成列表,也就是如果参数重复则会保存多个值;
append_const: 将参数规范中定义的一个值保存到一个列表;
count: 存储遇到的次数;此外,也可以继承 argparse.Action 自定义参数解析;
const: action 和 nargs 所需要的常量值。


6. 更多的关于参数解析:parse_args()

7. References

  1. 极客学院 argparse
  2. Argparse Tutorial (for python 3.6.6)
  3. argparse — Parser for command-line options, arguments and sub-commands

猜你喜欢

转载自blog.csdn.net/github_36326955/article/details/82682521