Python Fire:自动生成命令行接口

发布时间 2023-08-15 20:47:26作者: 北京测试菜鸟
  1. 首先创建一个 student_file.py
  2. pip install fire
  3. 使用 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__":
    # 子命令的名称分别是:import 和 export
    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}

  

  执行结果: