命令行参数用python实现有以下几种方式:

python内置模块sys和getopt

这种方式比较基础,话不多说上代码。

# args.py

import sys
import getopt


print(sys.argv)
opts, args = getopt.getopt(sys.argv[1:], 'hi:o:', ['help', 'input=', 'output='])
print(opts)
print(args)

for opt, arg in opts:
    if opt == '-h' or opt == '--help':
        print("这是一个帮助说明")
    elif opt == '-i' or opt == '--input':
        print('这是一个输入,输入内容是:' + arg)
    elif opt == '-o' or opt == '--output':
        print('这是一个输出,输出内容是:' + arg)


# 运行结果
$ python args.py -h -i 'input content' --output='output content'
['args.py', '-h', '-i', 'input content', '--output=output content']
[('-h', ''), ('-i', 'input content'), ('--output', 'output content')]
[]
这是一个帮助说明
这是一个输入,输入内容是:input content
这是一个输出,输出内容是:output content

sys.argv 返回的是列表,第一个元素是文件名,从第二个元素开始是命令行参数;

getopt.getopt(argsshortoptslongopts=[])   参数,短参数,长参数;短参后面冒号和长参后面等号代表这个参数必须有值,否则报错;

argparse模块

官方文档:argparse — 命令行选项、参数和子命令解析器 — Python 3.11.10 文档
这也是python内置模块,但是这个功能更强大,还能自动生成帮助信息;

ArgumentParser 对象

先放完整的使用代码,在下一个章节,结合add_argument()一起介绍。

# main.py

import argparse

# 创建一个解析器
parser = argparse.ArgumentParser(prog='点菜',
                                 description='菜单展示,有不同的菜系',
                                 epilog='祝您吃好喝好',
                                 prefix_chars='+-',
                                 allow_abbrev=True)
# 给解析器添加参数
parser.add_argument()

# 运行解析器
args = parser.parse_args()
print(args)
# 获取args的属性值
print(args.xxx)    #  xxx是dest的值

add_argument() 方法

官方文档的介绍,有些见名知意的参数,如type、choices、help就不会着重介绍了。

名称

描述

action

指明应当如何处理一个参数

'store''store_const''store_true''append''append_const''count''help''version'

choices

将值限制为指定的可选项集合

['foo', 'bar']range(1, 10) 或 Container 实例

const

存储一个常量值

default

当未提供某个参数时要使用的默认值

默认为 None

dest

指定要在结果命名空间中使用的属性名称

help

某个参数的帮助消息

metavar

要在帮助中显示的参数替代显示名称

nargs

参数可被使用的次数

int, '?''*' 或 '+'

required

指明某个参数是必需的还是可选的

True 或 False

type

自动将参数转换为给定的类型

int, float, argparse.FileType('w') 或可调用函数

表格中其实少了第一位的参数,name or flags,是一个可变参数*args,可传入位置参数或可选参数,位置参数即前面无-字符,可选参数默认以-开头。

位置参数

# positional argument 
parser.add_argument('max_value', type=float, metavar='Money', choices=[1000, 2000, 3000], help='点菜最大金额')
parser.add_argument('who', type=str, nargs='*', default=['red', 'green'], help='点菜的人')

# 运行结果
$ python main.py 1000
Namespace(max_value=1000.0, who=['red', 'green'])

$ python main.py 1000 'jack'
Namespace(max_value=1000.0, who=['jack'])

添加2个位置参数, metavar参数是帮助中显示的参数名称,如图所示,初始化解析器时prog展示到usage中,但usage可自定义会覆盖默认内容;description展示在参数上方,epilog展示在最底部。help的值展示到参数后方,说明这个参数的作用。

who这个位置参数设置了默认值,且nargs=*,所以可以不传参;*代表了【0-无数个】参数,?代表0或1个参数。当然如果nargs改为+,代表【1-无数个】参数,即便给了default的值,也是必须传参的,可以尝试下。所以除非位置参数中,设置了nargs='?' 或 '*',有必要设置default值。其余情况下,设置default也无用,还是必须传值。

# 测试位置参数的action使用,默认action是store
parser.add_argument('test_append', action='append')
parser.add_argument('test_extend', action='extend', nargs='*')
运行结果:
$ python main.py 1 2 3 4
Namespace(test_append=['1'], test_extend=['2', '3', '4'])

另外,在位置参数中设置action为store_true、 store_false、 store_const、 append_const
都是固定的值,无法通过传参来改变,虽然代码不会报错但是这样做并无太大意义;设置action为count、version、help更不合理。唯一能设置的可能也就append、extend了,代码和运行结果如上。action每个值的意思在可选参数中介绍。

还有对于位置参数,不可设置dest参数,因为会自动取第一个参数作为dest的值,如果再定义dest会报错; 而可选参数能自定义dest值,不定义的话按以下规则取: 第一个长选项字符串并去掉开头的 — 字符串来生成 dest 的值。 如果没有提供长选项字符串,则 dest 将通过接受第一个短选项字符串并去掉开头的 – 字符来获得。

可选参数
parser.add_argument('+c', '--count', dest='num', required=True, help='聚餐人数')

# 运行结果
$ python main.py +c=10
Namespace(num='10')
$ python main.py --co=10
Namespace(num='10')

dest 是命名空间中使用的属性名,从运行结果中可以看出,同样也是调用属性时所用的名称;

初始化解析器时prefix_chars='+-', allow_abbrev=True这两个参数什么意思呢?首先可以注意到上面的代码是+c,而不是-c,是因为prefix_chars支持了可选参数前是+;而allow_abbrev代表是否支持缩写,默认是True,所以上面代码使用–co执行就相当于–count。

required这个参数设置为True,代表这个参数必须传值,但是官方文档是不推荐的,因为用户会预期 options 都是 可选的,因此在可能的情况下应当避免使用它们。

以下重点介绍action参数:

action默认值是store,存储参数值。

# store_const 当使用该选项--kinds_num,会自动赋值
parser.add_argument('--kinds_num', action='store_const', const=5, metavar='V',  help='点菜的类型最少几种,热菜、凉菜、甜点等')
# store_true /store_false
parser.add_argument('--foo', action='store_true', help='默认关闭开关,加上该参数是true')
# append_const 适用于多个参数需要将常量存储到同一列表
parser.add_argument('--value1', dest='value', action='append_const', const='hello world')
parser.add_argument('--value2', dest='value', action='append_const', const=str)
# count 计算参数出现次数,一般日志等级用到,-vvv, 得到 verbose=3
parser.add_argument('-v', '--verbose', action='count')
# 获取版本号
parser.add_argument('--version', '-V', action='version', version='1.4')


# append 参数值加到列表中,需多次指定
parser.add_argument('-add', action='append', help='加菜')
# -add 'sweet' -add 'hot' 需这样指定,结果是 add=['sweet', 'hot']

# extend 参数值加到列表中,可一次指定多个
parser.add_argument('-adda', action='extend', nargs='*', help='加菜')
# -adda 'sweet' 'hot'这样写,结果是 adda=['sweet', 'hot']

"""
parser.add_argument('-add', action='append', nargs='*', help='加菜')
# -add 'sweet' -add 'hot' 这样写,结果是 add=[['sweet'], ['hot']]
# -add 'sweet' 'hot' 这样写,结果是 add=[['sweet', 'hot']]
"""

运行结果
$ python main.py --kinds_num --foo --value1 --value2 -vv -add 'sweet' -add 'hot' -adda 'sweet' 'hot'
Namespace(kinds_num=5, foo=True, value=['hello world', <class 'str'>], verbose=2, add=['sweet', 'hot'], adda=['sweet', 'hot'])
$ python main.py --version
1.4

除了append和extend,其余action类型都是不需要传值的,因为都属于指定默认值的类型。如果你非要传–foo=1,那只能报错了。而version比较特殊,只要参数中包含了-V或–version,那只返回版本号,同-h。

全部的代码都放开注释,通过args.(dest名称) 获取args的参数值:

print(args)
print(args.who, args.num, args.value, args.verbose)

运行结果:
$ python main.py --kinds_num --foo --value1 --value2 -vv -add 'sweet' -add 'hot' -adda 'sweet' 'hot' +c=10 1000

Namespace(max_value=1000.0, who=['red', 'green'], num='10', kinds_num=5, foo=True, value=['hello world', <class 'str'>], verbose=2, add=['sweet', 'hot'], adda=['sweet', 'hot'])

['red', 'green'] 10 ['hello world', <class 'str'>] 2

查看帮助如图:

小结

其实解析命令行参数,还有optparse,感兴趣的自行了解~

官网上还提供了这样一组代码,通过上面的学习,看下是否能理解呢

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

作者:测试盐

物联沃分享整理
物联沃-IOTWORD物联网 » python设置命令行选项

发表回复