工作中会经常需要写一些命令行脚本,如果还是用if,else判断用户输入实在是太丑陋了。这里介绍几个python里的命令行脚本库,可以帮助我们快速开发好用的命令行脚本。
cmd
https://docs.python.org/3/library/cmd.html
class cmd.Cmd(completekey='tab', stdin=None, stdout=None)
使用方式是继承Cmd,实现自己的子类。
参数comletekey是自动补全操作,默认值是Tab, 如果不为None 且readline可用的话,命令会自动完成。
这里的readline指的是python实现的GNU readline接口(标准python库里没有,Windows系统不支持)。
GNU Readline是一个软件库,可为具有命令行界面(例如Bash)的交互式程序提供行编辑器和历史记录功能。
用户可以移动文本光标,搜索命令历史,控制kill ring(一个更灵活的剪贴板),并在文本终端上使用Tab键自动完成。作为一个跨平台的库,readline允许不同系统上的应用程序展现相同的行编辑行为。
参数stdin,stdout是输入输出流,默认是sys.stdin,sys.stout。
例子
import cmd
class PerfShell(cmd.Cmd):
intro = 'Welcome to the perf shell. Type help or ? to list commands.\n'
prompt = '(perf) '
file = None
def do_static_mem_test(self, arg):
'静态内存测试'
print(arg)
def do_bye(self, arg):
'Stop recording, close the turtle window, and exit: BYE'
print('Thank you for using Turtle')
self.close()
return True
# ----- record and playback -----
def do_record(self, arg):
'Save future commands to filename: RECORD rose.cmd'
self.file = open(arg, 'w')
def do_playback(self, arg):
'Playback commands from a file: PLAYBACK rose.cmd'
self.close()
with open(arg) as f:
self.cmdqueue.extend(f.read().splitlines())
def precmd(self, line): #命令行执行前的钩子函数
line = line.lower()
if self.file and 'playback' not in line:
print(line, file=self.file)
return line
def close(self):
if self.file:
self.file.close()
self.file = None
if __name__ == '__main__':
PerfShell().cmdloop()`
使用
使用.pngcmd提供了一个简单的框架,但是功能比较简单,python还有其他的很多第三方库可以用来写命令行程序。
https://www.cnblogs.com/xueweihan/p/12293402.html 这篇文章对比了各个库的功能,贴在这里:
image.png看起来fire是最简单的,来试一下。
fire
fire 则是用一种面向广义对象的方式来玩转命令行,这种对象可以是类、函数、字典、列表等,它更加灵活,也更加简单。你都不需要定义参数类型,fire 会根据输入和参数默认值来自动判断,这无疑进一步简化了实现过程。
以下示例为 fire 实现的 计算器程序:
import sys
import fire
sys.argv = ['calculator.py', '1', '2', '3', '--sum']
builtin_sum = sum
# 1. 业务逻辑
# sum=False,暗示它是一个选项参数 --sum,不提供的时候为 False
# *nums 暗示它是一个能提供任意数量的位置参数
def calculator(sum=False, *nums):
"""Calculator Program."""
print(sum, nums) # 输出:True (1, 2, 3)
if sum:
result = builtin_sum(nums)
else:
result = max(nums)
print(result) # 基于上文的 ['1', '2', '3', '--sum'] 参数,处理函数为 sum 函数,其结果为 6
fire.Fire(calculator)
从上述示例可以看出,fire 提供的方式无疑是最简单、并且最 Pythonic 的了。我们只需关注业务逻辑,而命令行参数的定义则和函数参数的定义融为了一体。
不过,有利自然也有弊,比如 nums 并没有说是什么类型,也就意味着输入字符串'abc'也是合法的,这就意味着一个严格的命令行程序必须在自己的业务逻辑中来对期望的类型进行约束。
网友评论