You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pythonfire/fire底层原理浅析:.md

3.9 KiB

fire底层原理浅析

我们都知道使用python fire可以将函数、类、对象等变成命令行接口例如下面的例子;

import fire

def hello(word):

print('hello {} !'.format(word))

fire.Fire(hello)

要使用Python Fire将这个函数变成命令行接口只需执行以下命令

python test.py --word='world'

就会输出:

  • image-20240426155406113

看上去当我们写了一个很大的项目时想要调试的时候不需要运行完整的项目而是只要使用FIre函数将hello函数传递给它这样就可以生成一个命令行接口了那么对于fire模块来说它的底层是怎么工作的呢

1、反射机制

在介绍这个机制之前我们需要了解python语言的一种特别的机制——内省机制所谓内省是指编程语言能够检查一些对象在运行时的类型和属性的能力。Python 内省能力强大允许开发者编写灵活和动态的代码。使用内省你可以在运行时检查对象如模块、类、实例、函数等确定它们的类型它们有哪些属性甚至它们的文档字符串。而fire库的反射机制正是通过python的内省功能来实现的

比如这两个方法type()和isinstance()

type() 函数用来获取任何对象的类型。isinstance() 则用来检查一个对象是否是一个类的实例或者是一个子类的实例。

再比如python里inspect模块里的 getattr(), setattr(), hasattr(), 和 delattr()函数`

这些函数用于在运行时获取、设置、检查和删除对象的属性。

让我们从源代码开始分析:

image-20240426222935137

这段代码里,根据命令行参数名称列表 arg_names,在对象的成员列表 members 中查找匹配的成员。如果找到匹配的成员,则返回对应的属性或方法对象,并将当前的命令行参数值和剩余的参数列表作为结果返回。如果未找到匹配的成员,则抛出异常。

2、命令生成

Fire 使用 inspect 模块分析对象提取其方法、属性和文档字符串等信息后接下来就会创建命令了它会对于对象里的每一个方法创建一个同名命令这些方法的参数就会成为命令的参数命令创建完成后接下来fire会进行参数解析使用argparse 模块解析命令行参数并且它会自动将参数值转换为适当的数据类型并根据方法的参数注释进行验证这样当命令被调用时fire使用解析后的参数调用相应的方法。

image-20240427122113677

在这段代码里,函数创建一个用于解析命令行参数的 parser对象定义了一些常见的命令行选项--verbose--interactive--separator--completion--help--trace

3、命令行解析器

首先, Fire 创建一个 Command 对象,并将命令行参数传递给该对象。接着, Command 对象使用 _parse_args() 函数解析命令行参数。Command 对象根据解析后的参数调用相应的命令。

4.帮助文档生成

fire的帮助文本由helptext模块的HelpText类生成 HelpText 类收集命令信息并生成帮助文本,包括命令名称、描述、参数、选项和示例

image-20240427154637648

在这段代码里函数创建了几个组件的信息例如name_section、synopsis_section、description_section等等将各个部分格式化为字符串并通过换行符连接起来生成最终的详细信息字符串。