用argparse实现任意类型的命令行参数

2019年12月11日 / 257次阅读 / Last Modified 2019年12月12日
argparse模块

用python做命令行程序很幸福,因为有一个argparse模块,这个模块专门支持开发命令行程序。命令行程序有各种参数,不同参数的类型还不一样,本文介绍如何使用argparse模块提供的接口,来实现命令行任意参数类型,以及对参数的检查。

默认情况下,argparse模块生成的命令行接口,接收的都是字符串(有空格就用双引号括起来)类型参数。add_argument函数有一个type参数,用来指定参数的类型。

下面这段代码,展示了默认是type=str类型的参数:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('echo')
args = parser.parse_args()
print(args.echo)
print(type(args.echo))

运行效果如下:

E:\py>python arg.py 123
123
<class 'str'>
E:\py>python arg.py "123 456 789"
123 456 789
<class 'str'>

如果我们加上type参数,指定参数类型为int,代码如下:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('echo', type=int)
args = parser.parse_args()
print(args.echo)
print(type(args.echo))

修改type=int后,运行效果如下:

E:\py>python arg.py 123
123
<class 'int'>
E:\py>python arg.py "123 456"
usage: arg.py [-h] echo
arg.py: error: argument echo: invalid int value: '123 456'
E:\py>python arg.py "123"
123
<class 'int'>

type还可以使用float类型,修改代码如下:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('echo', type=float)
args = parser.parse_args()
print(args.echo)
print(type(args.echo))

修改为type=float之后,运行效果如下:

E:\py>python arg.py 123
123.0
<class 'float'>
E:\py>python arg.py "123 456"
usage: arg.py [-h] echo
arg.py: error: argument echo: invalid float value: '123 456'
E:\py>python arg.py "123.456"
123.456
<class 'float'>

type还可以设置为任意类型!

type指向的实际上是一个参数转换函数,代码首先从命令行获取参数字符串,以上示例中,默认用str()转换,当type=int时,就用int()转化,当type=float时,就是用float()函数来转换。因此,我们可以自己定义一个转换函数,来实现任意参数类型!

下面的示例,在命令行输入一个0x开始的十六进制字节数,转换函数实现0x开始的十六进制字节到int的转换:

import argparse


def take1byte(string):
    """change one-hex-byte to a real byte number"""
    check_list = ['0','1','2','3','4','5','6','7','8','9',
                  'A','B','C','D','E','F']
    if (len(string) != 4 or
        string[0:2] != '0x' or
        string[2] not in check_list or
        string [3] not in check_list): 
        msg = 'Not a valid one-hex-byte with 0x prefix, in upper case.'
        raise argparse.ArgumentTypeError(msg)
    return int(string[2:],16) 


parser = argparse.ArgumentParser()
parser.add_argument('--hex', required=True, type=take1byte)
args = parser.parse_args()
print('your input number is :', str(args.hex))

这段测试代码,显示了--hex参数只能接收0x开始的大写的十六进制字节,运行效果如下:

E:\py>python arg.py --hex=0x10
your input number is : 16
E:\py>python arg.py --hex=0xAA
your input number is : 170
E:\py>python arg.py --hex=0xFF
your input number is : 255
E:\py>python arg.py --hex=FF
usage: arg.py [-h] --hex HEX
arg.py: error: argument --hex: Not a valid one-hex-byte with 0x prefix, in upper
 case.

type=take1byte,转换函数take1byte函数的入参是一个字符串,如果在解析参数的时候出现错误,通过抛出argparse.ArgumentTypeError异常来实现命令行界面的提示信息,最后return返回真正的参数值。

再来一个示例,这个参数通过1+2+3...这样的方式获取参数,数字范围从1到12,可以重复+某个数字,转换函数将其转换成一个集合set类型:

import argparse


def takeslotset(string):
    """get slot set"""
    slot_set_str = set(string.split('+'))
    slot_set = set()
    for item in slot_set_str:
        if item not in ['1','2','3','4','5','6','7','8','9','10','11','12']:
            raise argparse.ArgumentTypeError(f'slot number error:{item}')
        slot_set.add(int(item))
    return slot_set


parser = argparse.ArgumentParser()
parser.add_argument('--slot', required=True, type=takeslotset)
args = parser.parse_args()
print('slot set:', args.slot)

再重复一下转换函数的几个关键点:(1)字符串入参;(2)检查参数如果错误,抛出argparse.ArgumentTypeError异常;(3)return真正的参数值。

以上代码运行效果如下:

E:\py>python arg.py --slot=1+2+3
slot set: {1, 2, 3}

E:\py>python arg.py --slot=1+2+3+12
slot set: {1, 2, 3, 12}

E:\py>python arg.py --slot=1+2+3+12+24
usage: arg.py [-h] --slot SLOT
arg.py: error: argument --slot: slot number error:24

E:\py>python arg.py --slot=1+2+3+3+3+3
slot set: {1, 2, 3}

通过type这个参数后面接任意转换函数,我们就实现了python命令行程序任意参数类型!

-- EOF --

本文链接:https://www.pynote.net/archives/1599

留言区

《用argparse实现任意类型的命令行参数》有1条留言

电子邮件地址不会被公开。 必填项已用*标注

  • 麦新杰

    注意一个细节:可以是--slot 1+2+3,也可以是--slot=1+2+3,可以用等号链接参数名称和具体参数内容。 [回复]


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top