我们经常需要调整程序的执行行为,最佳实践应该是:实现规范的命令行参数 ,而不是动不动就去改代码。试想一下,程序配置文件路径是通过命令行指定好呢?还是写死在代码里好呢?
每个程序都应该实现 -h 或者 –help 参数选项,输出帮助信息。这样一来,谁都可以通过该途径获悉程序用法,应用自如。这便是惯例的力量!
实现命令行参数的成本也不高,大部分语言都提供了足够方便的程序库,无需也不推荐重复造轮子。Python 程序可以通过标准库 argparse 解析命令行参数。
快速上手
接下来,以一个名为 AgentX 的程序为例,讲解如何使用 argparse 模块。AgentX 的用法如下:
1
2
3
4
5
6
7
8
9
10
|
$ python agentx.py -h
usage: agentx [-h] [-c conf_path] action
positional arguments:
action action to carry out: status/start/stop
optional arguments:
-h, --help show this help message and exit
-c conf_path, --conf conf_path
configuration file path
|
-h 选项显示帮助文档;-c 选项指定配置文件目录;位置参数 action 指定要执行的操作。
借助 argparse ,解析命令行参数只需代码若干:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
import argparse
class ServiceController(object):
'''
服务控制器
根据命令行参数,操作后台服务(守护进程)。
'''
def __init__(self, conf_path):
# 命令行参数
self.conf_path = conf_path
def status(self):
'''
查询服务运行状态
'''
print('service is ...')
def start(self):
'''
启动服务
'''
print('starting')
def stop(self):
'''
停止服务
'''
print('stopping')
def process(self, action):
'''
处理入口
'''
getattr(self, action)()
def main():
'''
主函数
负责处理命令行参数并调用服务控制器。
'''
# 命令行解析
parser = argparse.ArgumentParser(prog='agentx')
# 配置文件选项
parser.add_argument(
'-c',
'--conf',
dest='conf_path',
metavar='conf_path',
default='',
required=False,
help='configuration file path',
)
# 操作选项
parser.add_argument(
'action',
nargs=1,
metavar='action',
choices=('status', 'start', 'stop',),
help='action to carry out: status/start/stop',
)
# 解析
args = parser.parse_args()
# 配置文件路径
conf_path = args.conf_path
# 执行动作
action, = args.action
# 处理
service_controller = ServiceController(conf_path=conf_path)
service_controller.process(action=action)
if __name__ == '__main__':
main()
|
第 19~57 行是服务控制类 ServiceController 定义,我们需要根据命令行参数驱动该类执行选定逻辑。而参数解析部分却只有一小段,位于 main 函数:
- 68 行先初始化一个参数解析器, prog 参数是程序名字;
- 82 行是 -c 参数的定义: dest 执行参数值存放位置; metavar 是选项名称占位符,与 help 结合在帮助文档中显示; default 是默认值; required 指定选项是否必填;
- 82 行是位置参数 action 的定义:nargs 指定参数个数,这里为 1 ;choices 指定参数可选值;
- 91 行调用解析器进行解析;
- 94 行从解析结果中取值,注意到属性名和参数定义中 dest 参数一致;
总结起来,参数解析只需要这几个步骤:
- 初始化解析器;
- 定义选项;
- 调用解析器解析参数;
- 从解析结果取值;
【小菜学Python】系列文章首发于公众号【小菜学编程】,敬请关注: