让Python程序接收命令行参数:optparse库的使用
如何让python脚本接收到命令行的参数是压在我们不愿意做图形化界面懒狗面前的一座大山,但我也就写写小工具没做UI的必要。所以今天我去稍微了解了一下optparse这个默认库,在平时的使用场景也比较多。学前提示,这个库目前以停止更新,如果需要更多的功能可以去学习argparsse这个库。
明确目标
首先让我们假设一下,在我们本地的9000端口有一个接口,当我们去请求http://127.0.0.1:9000/hello
会返回我们一个Hello World!
。而我们的脚本所要完成的功能就是请求后端接口并选择是否将返回输出在命令行中。
我们分析一下可知我们应该需要一下几个参数:
- 后端程序的IP(-i –ip)
- 后端程序的端口(-p –port)
- 后端程序的接口(-u –url)
- 是否需要输出在终端中(-o –output)
我们将其转换成终端中运行时带参数的命令应该是这样的:
1
| python request.py -i 127.0.0.1 -p 9000 -u /hello -o
|
编写代码
当我们明确了目标后我们就可以开始着手编写代码了,首先我们可以定义一个MyParse
的类,在其中定义一个初始化方法__init__
。定义完成后我们应该先初始化一个名为parser
的对象,并设置好我们的参数。
设置参数
1 2 3 4 5 6 7 8 9 10 11
| import optparse
class MyParse(object): def __init__(self): parser = optparse.OptionParser() parser.add_option("-i", "--ip", action="store", type=str, dest="ip", help="Server IP") parser.add_option("-p", "--port", action="store", type=str, dest="port", help="Server Port") parser.add_option("-u", "--url", action="store", type=str, dest="url", help="Server url") parser.add_option("-o", "--output", action="store_true", dest="output", help="Print respons to screen or not")
|
由以上代码我们可以发现我们使用了OptionParser
与add_option
这两个方法,前者是用于初始化对象不带参数,非常容易理解,所以我们就只解释一下add_option
这个方法。
我们分析一下第一句parser.add_option("-i", "--ip", action="store", type=str, dest="ip", help="Server IP")
与最后一句parser.add_option("-o", "--output", action="store_true", dest="output", help="Print respons to screen or not")
并对其进行比较。
前两个参数非常好理解是我们参数的缩写与全称。
而第三个参数action
是用来表示我们参数后到底带不带值,我们-i
这个参数是用来接收服务器ip的,所以毋庸质疑是需要带参数。那么store
也就是次参数后必须携带值,而store_true
后是不需要携带值的。
第四个参数type
顾名思义也就是来标示我们接收的值的类型,在这里我们就是string类型。因为-o
参数并不需要输入值所以也就可以省略去此参数,而-o
参数的接收值也是bool类型的,当我们调用了此参数就为True,而不调用则为None。
第五个参数dest
是给参数命名,在后来我们从代码中调用参数的值也正是使用这个名称。
最后一个参数help
也非常好理解,就是对我们这个参数的解释,在使用帮助命令时会被打印出来。
获取参数值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import optparse
class MyParse(object): def __init__(self): parser = optparse.OptionParser() parser.add_option("-i", "--ip", action="store", type=str, dest="ip", help="Server IP") parser.add_option("-p", "--port", action="store", type=str, dest="port", help="Server Port") parser.add_option("-u", "--url", action="store", type=str, dest="url", help="Server url") parser.add_option("-o", "--output", action="store_true", dest="output", help="Print respons to screen or not") self.options, self.args = parser.parse_args() print("self.options -> ",self.options) print("self.args -> ",self.args) if __name__ == "__main__": my_parse = MyParser()
|
直接运行的结果:
1 2 3
| > python request.py self.options -> {'ip': None, 'port': None, 'url': None, 'output': None} self.args -> []
|
在我们获取参数时,我们会用到两个属性options
与args
,还有一个parse_args
方法。由于parse_args
用法非常明了再次我们也不介绍了,就是获取接收到的值。而options
与args
就是存放我们接收到的值用的。
我们从代码的运行结果来看发现options
中存放的就是参数的值,输出中Key的值就是我们定义参数时dest
的值。由于我们并没有输入任何参数所以他们的Value都为None
。
而我们反观args
中却没有任何值,那么他是用来存放什么的呢?我们再次运行程序:
1 2 3
| > python request.py -i 127.0.0.1 -p 9000 -u /hello -o asdasd 123123 self.options -> {'ip': '127.0.0.1', 'port': '9000', 'url': '/hello', 'output': True} self.args -> ['asdasd', '123123']
|
我们在命令后加了很多不必要的参数,而这些参数值都被存在了args
中了。
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
| import optparse
class MyParse(object): def __init__(self): parser = optparse.OptionParser() parser.add_option("-i", "--ip", action="store", type=str, dest="ip", help="Server IP") parser.add_option("-p", "--port", action="store", type=str, dest="port", help="Server Port") parser.add_option("-u", "--url", action="store", type=str, dest="url", help="Server url") parser.add_option("-o", "--output", action="store_true", dest="output", help="Print respons to screen or not") self.options, self.args = parser.parse_args() print("self.options -> ",self.options) print("self.args -> ",self.args) def handle_options(self): print("ip: ", self.options.ip) print("port: ", self.options.port) if __name__ == "__main__": my_parse = MyParser() my_parse.handle_options()
|
看到这有些同学会跑去写代码去尝试获取参数,发现直接对options
用字典的方法去取值会报错。我们用type(self.option)
去输出一下会发现这个根本就不是字典类型。我们如果想获取参数的值则必须使用属性的方式来获取,比如获取ip
这个属性在__init__
方法中就应该是self.options.ip
。args
则不像options
,他就是一个列表,我们可以直接用self.args[0]
来获取值。
使用参数值
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
| import optparse import requests from datetime import datetime
class MyParse(object): def __init__(self): parser = optparse.OptionParser() parser.add_option("-i", "--ip", action="store", type=str, dest="ip", help="Server IP") parser.add_option("-p", "--port", action="store", type=str, dest="port", help="Server Port") parser.add_option("-u", "--url", action="store", type=str, dest="url", help="Server url") parser.add_option("-o", "--output", action="store_true", dest="output", help="Print respons to screen or not") self.options, self.args = parser.parse_args() print("self.options -> ",self.options) print("self.args -> ",self.args) def handle_options(self): print("ip: ", self.options.ip) print("port: ", self.options.port) def handle_hello_world(requset_url: str, output: bool): ret = requests.get(request_url) if ret.ststus_code != 200: print("请求错误") return curr_str = f"{str(datetime.now())} -> {ret.text}" if output is True: print(curr_str) if __name__ == "__main__": my_parse = MyParser() ip = my_parse.options.ip port = my_parse.options.port url = my_parse.options.url request_url = f"http://{ip}:{port}{url}" output = my_parse.options.output handle_hello_world(request_url, output)
|
1 2 3 4
| > python request.py --ip 127.0.0.1 --port 9000 --url /hello -o self.options -> {'ip': '127.0.0.1', 'port': '9000', 'url': '/hello', 'output': True} self.args -> [] 2022-04-17 00:59:10.015324 -> Hello World!
|
所使用的方法总结
方法名 |
作用 |
示例代码(取自以上代码中) |
OptionParser() |
初始化对象 |
parser = optparse.OptionParser() |
add_option() |
添加参数 |
parser.add_option(“-i”, “–ip”, action=”store”, type=str, dest=”ip”, help=”Server IP”) |
parse_args() |
获取参数值 |
self.options, self.args = parser.parse_args() |