python命令行解析工具-argparse模块-官方文档解读

python命令行解析工具-argparse模块-官方文档解读

    • 0.举个例子
    • 1.第一步:导包并创建对象
    • 2.第二步:添加自己所需命令行参数
    • 3.第三步:解析命令行参数
    • 4.第四步:Namespace对象
    • 5.再举一个例子
    • 6.Tips

0.举个例子

官方文档(Document)
源码(Source code)

argparse是python用来处理命令行参数的模块,本文主要简述python3下该模块的常见使用方法。先看一个官网简单的例子

  1. 新建.py文件test1.py,文件内容如下:

    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. 在命令行运行该文件并加上’-h’命令时,可以友好的输出上述代码自定义的所有帮助信息

    $ python3 test1.py -h
    usage: test.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)
    

    从帮助信息中可以解读到(位置参数与选项参数区别本节末会进行讲解):

    • 代码描述(description):处理多个整数
    • 位置参数(positional arguments):用于累加的整数
    • 选项参数(optional arguments):
      • -h 显示帮助信息并退出
      • –sum 对整数进行求和,(如果没有,则默认输入最大值)
  3. 下面进行简单的测试

    $ python3 test.py 3 5 6 4
    6
    
    $ python3 test.py 3 5 6 4 --sum
    18
    

    正如帮助信息中所述,在命令行后面只添加整数时,返回最大值;加入–sum时,返回所有整数的和

  4. 输入不按要求来呢?

    $ python3 test.py
    usage: test.py [-h] [--sum] N [N ...]
    test.py: error: the following arguments are required: N
    
    $ python3 test.py a b c d
    usage: test.py [-h] [--sum] N [N ...]
    test.py: error: argument N: invalid int value: 'a'
    
    $ python3 test.py --sum
    usage: test.py [-h] [--sum] N [N ...]
    test.py: error: the following arguments are required: N
    

    argparse可以输出部分提示信息,应对很优雅。

  5. 注: 位置参数和选项参数的小tips(Tips about the difference between positional arguments and optional arguments)
    在命令行中,命令行参数分为位置参数和选项参数。

    • “ls /Users/pro” ls命令后面的指定路径就是位置参数

      $ ls /Users/pro
      Applications Documents    Library      Music        Pictures
      Desktop      Downloads    Movies       Public
      
    • “ls -l -h” ls命令后面-l与-h就是选项参数(加横杠表示选项参数开关)

      $ ls -l -h
      drwxrwxrwx   6 pro  staff   192B  2 22 10:47 data1
      drwxr-xr-x   5 pro  staff   160B  2 22 09:50 data2
      drwxr-xr-x@ 10 pro  staff   320B  3 11 09:11 data3
      
    • 为什么选项参数有的加一个横杠,又有的是两个横杠的情况,如“-h”与“–help”

      • 命令行为了简化输入,选项参数可以合并,即"ls -l -h"命令与“ls -lh”是相等的。换句话说,大于一个字母的选项参数会被分别解析。“ls -help"会被解析成"ls -h -e -l -p”
      • 为了避免上述情况发生,多于一个字母的选项参数,使用两个横杠。

下面对argparse模块进行详细阐述

1.第一步:导包并创建对象

  1. 使用argparse的第一步就是导入该包,并且创建一个ArgumentParser对象

    import argparse
    parser = argparse.ArgumentParser()
    

    创建对象时,ArgumentParser该方法的参数一般只使用"description=",即

    import argparse
    parser = argparse.ArgumentParser(description='这个程序是做什么的')
    
  2. 所有参数

    parser = 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)
    
    参数 原文解释 中文释义
    prog The name of the program (default: sys.argv[0]) 程序名
    usage The string describing the program usage (default: generated from arguments added to parser) 程序使用说明(默认生成添加到对象的参数)
    description Text to display before the argument help (default: none) 程序描述(默认:空),一般只需要填写该选项
    epilog Text to display after the argument help (default: none) 后记(默认:空)
    parents A list of ArgumentParser objects whose arguments should also be included ArgumentParser对象的父对象的参数列表
    formatter_class A class for customizing the help output help说明格式
    prefix_chars The set of characters that prefix optional arguments (default: ‘-‘) 命令行参数的前缀(默认"-")
    fromfile_prefix_chars The set of characters that prefix files from which additional arguments should be read (default: None) 该读取其他参数的前缀文件的字符集(默认空)
    argument_default The global default value for arguments (default: None) 全局参数默认值(默认空)
    conflict_handler The strategy for resolving conflicting optionals (usually unnecessary) 解决冲突的策略(通常是不必要的)
    add_help Add a -h/–help option to the parser (default: True) 是否增加help选项(默认:是)
    allow_abbrev Allows long options to be abbreviated if the abbreviation is unambiguous. (default: True) 是否使用参数的缩写(默认:是)

2.第二步:添加自己所需命令行参数

  1. 向已创建的对象中添加自己所需的命令行参数

    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)')
    
  2. 所有参数

    parser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
    
    参数 原文解释 中文释义
    name or flags Either a name or a list of option strings, e.g. foo or -f, --foo. 必选,选项参数或位置参数选其一,
    action The basic type of action to be taken when this argument is encountered at the command line. 指定应如何处理命令行参数(默认store)
    nargs The number of command-line arguments that should be consumed. 参数数量
    const A constant value required by some action and nargs selections. 参数常量值
    default The value produced if the argument is absent from the command line. 参数默认值
    type The type to which the command-line argument should be converted. 参数数据类型
    choices A container of the allowable values for the argument. 参数值域
    required Whether or not the command-line option may be omitted (optionals only). 参数是否可忽略不写
    help A brief description of what the argument does. help说明信息
    metavar A name for the argument in usage messages. 参数在说明文档中的名字
    dest The name of the attribute to be added to the object returned by parse_args(). 对象的属性名
  3. 部分参数详解

    • name or flags:必选项,可以填入选项参数或者位置参数。例如,可以创建一个选项参数,如:
      parser.add_argument('-f', '--foo')
      
      位置参数,如:
      parser.add_argument('bar')
      
    • action:指定应如何处理命令行参数,默认为store
      • store 存储参数的值
        >>> 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_truestore_false 将命令行参数的值存储为True或False
        >>> 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'])
        
      • action参数还有append_constcounthelp 以及 version等值,平时用的不多,暂不做赘述

3.第三步:解析命令行参数

  1. ArgumentParser对象通过parse_args()方法解析参数。将命令行的每个参数根据第二步具体选项转换为相应的类型,然后赋值给Namespace对象并返回。
    >>> parser.parse_args(['--sum', '7', '-1', '42'])
    Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])
    
  2. 选项参数
    • 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 = argparse.ArgumentParser(prog='PROG')
      >>> parser.add_argument('-x')
      >>> parser.add_argument('--foo')
      >>> parser.parse_args(['--foo=FOO'])
      Namespace(foo='FOO', x=None)
      
    • 对于选项等于一个字符的短选项,选项和值可以直接连接:

      >>> parser = argparse.ArgumentParser(prog='PROG')
      >>> parser.add_argument('-x')
      >>> parser.add_argument('--foo')
      >>> 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')
      
    • 报错处理
      在解析命令行时,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
      
    • 模棱两可的错误,当出现"-1"可能是负数,可能是1选项参数时。选项参数和位置参数都可以解析的情况时

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

      解决方案,插入伪参数’ --’

      >>> parser.parse_args(['--', '-f'])
      Namespace(foo='-f', one=None)
      
    • 参数缩写,当短参数可以唯一确定长参数时,可以选择缩写

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

4.第四步:Namespace对象

可归为第三步,现单列出
parse_args()默认使用的简单类,用于创建保存属性并返回它的对象。

这个类是故意简单的,只是一个带有可读字符串表示的对象子类。如果您希望使用类似dict的属性视图,则可以使用标准Python惯用法,即vars()

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

5.再举一个例子

转一个GitHub上面一个批量修改制定目录下文件扩展名的python项目

# batch_file_rename.py
# Created: 6th August 2012

"""
This will batch rename a group of files in a given directory,
once you pass the current and new extensions
"""

# just checking
__author__ = 'Craig Richards'
__version__ = '1.0'

import os
import argparse


def batch_rename(work_dir, old_ext, new_ext):
    """
    This will batch rename a group of files in a given directory,
    once you pass the current and new extensions
    """
    # files = os.listdir(work_dir)
    for filename in os.listdir(work_dir):
        # Get the file extension
        split_file = os.path.splitext(filename)
        file_ext = split_file[1]
        # Start of the logic to check the file extensions, if old_ext = file_ext
        if old_ext == file_ext:
            # Returns changed name of the file with new extention
            newfile = split_file[0] + new_ext

            # Write the files
            os.rename(
                os.path.join(work_dir, filename),
                os.path.join(work_dir, newfile)
            )


def get_parser():
    parser = argparse.ArgumentParser(description='change extension of files in a working directory')
    parser.add_argument('work_dir', metavar='WORK_DIR', type=str, nargs=1,
                        help='the directory where to change extension')
    parser.add_argument('old_ext', metavar='OLD_EXT', type=str, nargs=1, help='old extension')
    parser.add_argument('new_ext', metavar='NEW_EXT', type=str, nargs=1, help='new extension')
    return parser


def main():
    """
    This will be called if the script is directly invoked.
    """
    # adding command line argument
    parser = get_parser()
    args = vars(parser.parse_args())

    # Set the variable work_dir with the first argument passed
    work_dir = args['work_dir'][0]
    # Set the variable old_ext with the second argument passed
    old_ext = args['old_ext'][0]
    if old_ext[0] != '.':
        old_ext = '.' + old_ext
    # Set the variable new_ext with the third argument passed
    new_ext = args['new_ext'][0]
    if new_ext[0] != '.':
        new_ext = '.' + new_ext

    batch_rename(work_dir, old_ext, new_ext)


if __name__ == '__main__':
    main()

运行该文件

$ ls
1.txt                3.txt                geektest.iml
2.txt                batch_file_rename.py

$ python3 batch_file_rename.py /data3/github/geektest .txt .c

$ ls
1.c                  3.c                  geektest.iml
2.c                  batch_file_rename.py 

6.Tips

  • 本文参照官方文档,结合自己使用,对argparse模块做了简要说明。
  • 如有不妥,请指示正,谢谢阅读!
    作者:togetlife

你可能感兴趣的:(python)