Python Fire:自动生成命令行接口
- 首先创建一个 student_file.py
- pip install fire
- 使用
Fire转换成命令行程序
1. 默认方式
import fire
def import_file(fp):
print("函数1打印结果: {}".format(fp))
def export_file(fp):
print("函数2打印结果: {}".format(fp))
if __name__ == "__main__":
fire.Fire()
# 终端输入: python student_file.py import_file --fp ./path/xxx.csv
# 终端输入: python student_file.py export_file --fp ./path/xxx.csv
执行结果:

2. Fire<fn>
Fire库的默认方式会把所有的函数都转换为子命令,
如果只想导出一个函数的话,可以用 Fire<fn>的方式。
import fire
def import_file(fp):
print("函数1打印结果: {}".format(fp))
def export_file(fp):
print("函数2打印结果: {}".format(fp))
if __name__ == "__main__":
fire.Fire(import_file)
# 终端输入: python student_file.py --fp ./path/xxx.csv
执行结果:

3. Fire<dict>
导出多个函数作为子命令时,默认是使用函数名作为子命令名称的,函数名称有时候会非常长,输入很麻烦。可以用 Fire<dict> 方式
import fire
def import_file(fp):
print("函数1打印结果: {}".format(fp))
def export_file(fp):
print("函数2打印结果: {}".format(fp))
if __name__ == "__main__":
# 子命令的名称分别是:name和 age
fire.Fire({
"name": import_file,
"age": export_file,
})
# 终端输入: python student_file.py name --fp ./path/xxx.csv
# 终端输入: python student_file.py age --fp ./path/xxx.csv
执行结果:

4. Fire<object>
除了导出函数,Fire<object>方式也可以导出对象的公有方法。
import fire
class FileHandler:
def import_file(self, fp):
print("类里函数1打印结果: {}".format(fp))
def export_file(self, fp):
print("类里函数2打印结果: {}".format(fp))
if __name__ == "__main__":
fh = FileHandler()
fire.Fire(fh)
# 终端输入: python student_file.py import_file --fp ./path/xxx.csv
# 终端输入: python student_file.py export_file --fp ./path/xxx.csv
执行结果:

使用对象的方式没有直接使用函数那么简单,但有个好处是可以在初始化时传入一些数据。
import fire
class FileHandler:
def __init__(self, folder):
self.folder = folder
def import_file(self, fp):
print("类里函数1打印结果: 你的名字是{}你的年龄是{}".format(self.folder, fp))
def export_file(self, fp):
print("类里函数2打印结果: 你的名字是{}你的年龄是".format(self.folder, fp))
if __name__ == "__main__":
fh = FileHandler("python")
fire.Fire(fh)
# 终端输入: python student_file.py import_file --fp 25
# 终端输入: python student_file.py export_file --fp 25
执行结果:

5. Fire<class>
Fire<class>的方式也可以直接作用在类上,不用初始化对象。
import fire
class FileHandler:
def __init__(self, folder):
self.folder = folder
def import_file(self, fp):
print("类里函数1打印结果: 你的名字是{}你的年龄是{}".format(self.folder, fp))
def export_file(self, fp):
print("类里函数2打印结果: 你的年龄是{}".format(fp))
if __name__ == "__main__":
fire.Fire(FileHandler)
# 终端输入: python student_file.py import_file --fp 25 --folder python
# 终端输入: python student_file.py export_file --fp 25 --folder python
和 Fire<object> 不同的是,__init__方法的参数也变成了命令的参数,也可以在命令行中调整了。
执行结果:

6. 组合命令
功能越来越多时,可能就会需要组合一些功能一起运行,省得输入一个一个的子命令。
import fire
class FileHandler:
def __init__(self, folder="python"):
self.folder = folder
def import_file(self, fp):
print("import_file: 姓名{}, fp{}".format(self.folder, fp))
def export_file(self, fp):
print("export_file: 姓名{}, fp{}".format(self.folder, fp))
class DatabaseHandler:
def __init__(self, src="aliyun-mysql", dst="tecent-mysql"):
self.src = src
self.dst = dst
def import_db(self):
print("数据库db: {} to: {}".format(self.src, self.dst))
def export_db(self):
print("数据库export_db: {} to: {}".format(self.src, self.dst))
# 组合 FileHandler 和 DatabaseHandler
class ComposeHandler:
def __init__(self):
self.fhfh = FileHandler()
self.dhdh = DatabaseHandler()
def import_all(self, fp):
self.fhfh.import_file(fp)
self.dhdh.import_db()
def export_all(self, fp):
self.fhfh.export_file(fp)
self.dhdh.export_db()
if __name__ == "__main__":
fire.Fire(ComposeHandler)
# 终端输入: python student_file.py import_all --fp 22
# 终端输入: python student_file.py export_all --fp 22
# 导出组合命令之后,不仅可以执行组合命令,也可以只执行子命令
# 终端输入: python student_file.py fhfh export_file --fp 22
# 终端输入: python student_file.py dhdh export_db
执行结果:

7.链式命令
链式命令和组合命令不一样的地方在于:
组合命令中,每个命令之间一般是相互独立的,
而链式命令中,上一个命令的执行结果会对下一个命令造成影响。
import fire
class Stat:
def __init__(self):
self.avg = 0
self.n = 0
self.num = 2
def sum(self, a):
self.n += a
return self
def average(self):
self.avg = self.n / self.num
return self
def show(self):
print("和是:{}, and 平均值是:{}".format(self.n, self.avg))
if __name__ == "__main__":
fire.Fire(Stat)
# 终端输入: python student_file.py sum 10 average show
# 因为是链式命令,所以可以多次执行:
# python student_file.py sum 10 sum 20 sum 30 average show
执行结果:

8.复杂命令参数
复杂的命令参数如何使用,复杂的参数,就是元组,列表,字典等等
import fire
def hello(case):
tp = type(case).__name__
if tp == "tuple" or tp == "list":
for item in case:
print("hello: {}".format(item))
if tp == "dict":
for k, v in case.items():
print("hello: key {}, val {}".format(k, v))
if __name__ == "__main__":
fire.Fire(hello)
# 终端输入: python student_file.py "(aa, bb, cc)"
# 终端输入: python student_file.py "[aa, bb, cc]"
# 终端输入: python student_file.py "{aa: 11, bb: 22}
执行结果:
