python如何优雅地在命令行传入参数?sys,argparse,click使用
前言
一些大型的python
项目经常性会提供命令行的接口使得同样一个文件能够根据参数的不同执行不同的操作。常见的如python main.py --name='zhangsan' --age=20
,这让用户能够需求选择不同的服务启动并选择不同的参数配置,实现这一操作的方法有很多,比较常见的是三种:sys
,argparse
,click
。
sys
sys
是python
自带的模块,可以通过sys.argv
获取到输入的参数,如下所示:
import sys
def hello():
print(sys.argv)
if __name__ == '__main__':
hello()
# python3 test.py hey 23
# >> ['test.py', 'hey', '23']
sys.argv
返回一个列表,第一项是执行的文件名,后面依次是输入的未指定参数。
该模块十分简单易懂且方便使用,不过缺点也很明显,无法指定参数的名称,输入的参数必须按照指定顺序,且没有help
打印帮助信息(指明每个参数的作用),需要开发者手动创建一个。
argparse
argparse
是一个非常好用的命令行参数工具,相比于sys
,它能够指定参数名称,参数默认值,参数的描述信息等,具体如下:
import argparse
def hello(args):
print(args)
print(args.name,args.age)
if __name__ == '__main__':
my_arg = argparse.ArgumentParser('My argument parser')
my_arg.add_argument('--name','-n',default='cp',type=str,help='Your name')
my_arg.add_argument('--age','-a',default=24,type=int,help='Your age')
args = my_arg.parse_args()
hello(args)
通过声明一个
ArgumentParser
对象,再为其添加相应的输入参数,最后进行parse_args()
参数解析就可以获得从命令行输入的参数。这种方式的好处主要包括:
- 参数顺序随意,按照参数名称指定且名称(
--name
)可以用简称(-a
)减少输入 - 包含
help
帮助信息,可以让使用者快速理解每个参数的含义 - 可以设定默认值和数据类型
但这种方式必须要给出参数名称,不像sys
那样按顺序输入参数即可。
click
click
这个模块也是我近期才用到的,在一些大型项目中出现较多(特别是flask
的项目),用click
能够用更少的代码实现与argparse
类似的功能,且看起来更加简洁。
import click
@click.command()
@click.option('--name',default= 'cp',type=str,help='Your name')
@click.option('--age',default=24, type=int,help='Your age')
def hello(name,age):
print(name,age)
if __name__ == '__main__':
hello()
可以发现
click
将一个函数(hello()
)封装成了一个命令行接口,函数的输入参数由option
提供的参数决定。需要注意的是hello(name,age)
中的name,age
参数名是与option
指定的命令行参数名称对应的,因此不能任意改成其他名称。click.option
还有一个参数required
可以设置参数是否需要,如果设置False
,且没有给定默认值,那返回结果是None
,如果设定True
且没有输入值则会报错。
click.group
click
还有一个重要的方法group
,他允许将多个函数接口连接起来,形成一组,然后依次执行,具体实例如下:import click @click.group() def one(): print("hello one") @click.command(name='second') @click.option("--name", help="Your name") def two(name): print("hello two: {}".format(name)) @click.command() @click.option("--age", help="Your age") def three(age): print("hello three:{}".format(age)) if __name__ == '__main__': one.add_command(two) one.add_command(three) one()
在这个例子中,我给two()
函数的command
添加了name
属性,使得在调用的时候可以用second
替代two
进行接口调用。上面的方式的好处在于被group
装饰的函数是我们确定一定要执行的,而另外两个加入group
的函数则根据我们命令行参数的输入执行。click.argument
除了click.option
添加参数以外,click
还可以通过click.argument
添加参数,与option
不同的是,argument
直接指定参数名(没有--
),且是按照顺序输入(有点类似sys.argv
),如下例子:import click @click.command() @click.argument('ip',type=str) @click.argument('port',type=int) def hello(ip, port): print("ip:{},port:{}".format(ip,port)) if __name__ == '__main__': hello() # python3 test.py '10.1.1.1' 1234 # >> ip:10.1.1.1,port:1234
总结
本文讲述了三种在命令行执行python
文件时传入参数的方式,sys
胜在简便,在一般个人的小项目中可以图方便使用,argparse
更为正式,对参数的传递有严格的把控,click
兼具上面两者,且代码可读性强,适合大型的项目。三者根据自己需要选择使用。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!