|
|
|
@ -0,0 +1,59 @@
|
|
|
|
|
fire底层原理浅析:
|
|
|
|
|
|
|
|
|
|
我们都知道使用python fire可以将函数、类、对象等变成命令行接口,例如下面的例子;
|
|
|
|
|
|
|
|
|
|
`import fire`
|
|
|
|
|
|
|
|
|
|
`def hello(word):`
|
|
|
|
|
|
|
|
|
|
`print('hello {} !'.format(word))`
|
|
|
|
|
|
|
|
|
|
`fire.Fire(hello)`
|
|
|
|
|
|
|
|
|
|
要使用Python Fire将这个函数变成命令行接口,只需执行以下命令:
|
|
|
|
|
|
|
|
|
|
python test.py --word='world'
|
|
|
|
|
|
|
|
|
|
就会输出:
|
|
|
|
|
|
|
|
|
|
- ![image-20240426155406113](C:\Users\86135\AppData\Roaming\Typora\typora-user-images\image-20240426155406113.png)
|
|
|
|
|
|
|
|
|
|
看上去,当我们写了一个很大的项目时,想要调试的时候,不需要运行完整的项目,而是只要使用FIre函数,将hello函数传递给它,这样就可以生成一个命令行接口了,那么对于fire模块来说它的底层是怎么工作的呢?
|
|
|
|
|
|
|
|
|
|
1、反射机制:
|
|
|
|
|
|
|
|
|
|
在介绍这个机制之前,我们需要了解python语言的一种特别的机制——内省机制,所谓内省,是指编程语言能够检查一些对象在运行时的类型和属性的能力。Python 内省能力强大,允许开发者编写灵活和动态的代码。使用内省,你可以在运行时检查对象(如模块、类、实例、函数等),确定它们的类型,它们有哪些属性,甚至它们的文档字符串。而fire库的反射机制正是通过python的内省功能来实现的
|
|
|
|
|
|
|
|
|
|
比如这两个方法:type()和isinstance()
|
|
|
|
|
|
|
|
|
|
`type()` 函数用来获取任何对象的类型。`isinstance()` 则用来检查一个对象是否是一个类的实例或者是一个子类的实例。
|
|
|
|
|
|
|
|
|
|
再比如python里inspect模块里的 getattr()`, `setattr()`, `hasattr()`, 和 `delattr()函数`
|
|
|
|
|
|
|
|
|
|
这些函数用于在运行时获取、设置、检查和删除对象的属性。
|
|
|
|
|
|
|
|
|
|
让我们从源代码开始分析:
|
|
|
|
|
|
|
|
|
|
![image-20240426222935137](C:\Users\86135\AppData\Roaming\Typora\typora-user-images\image-20240426222935137.png)
|
|
|
|
|
|
|
|
|
|
这段代码里,根据命令行参数名称列表 `arg_names`,在对象的成员列表 `members` 中查找匹配的成员。如果找到匹配的成员,则返回对应的属性或方法对象,并将当前的命令行参数值和剩余的参数列表作为结果返回。如果未找到匹配的成员,则抛出异常。
|
|
|
|
|
|
|
|
|
|
2、命令生成:
|
|
|
|
|
|
|
|
|
|
Fire 使用 `inspect` 模块分析对象,提取其方法、属性和文档字符串等信息后,接下来就会创建命令了,它会对于对象里的每一个方法,创建一个同名命令,这些方法的参数就会成为命令的参数,命令创建完成后,接下来fire会进行参数解析,使用`argparse` 模块解析命令行参数,并且它会自动将参数值转换为适当的数据类型,并根据方法的参数注释进行验证,这样当命令被调用时,fire使用解析后的参数调用相应的方法。
|
|
|
|
|
|
|
|
|
|
![image-20240427122113677](C:\Users\86135\AppData\Roaming\Typora\typora-user-images\image-20240427122113677.png)
|
|
|
|
|
|
|
|
|
|
在这段代码里,函数创建一个用于解析命令行参数的 parser对象,定义了一些常见的命令行选项,如 `--verbose`、`--interactive`、`--separator`、`--completion`、`--help` 和 `--trace`。
|
|
|
|
|
|
|
|
|
|
3、命令行解析器:
|
|
|
|
|
|
|
|
|
|
首先, Fire 创建一个 `Command` 对象,并将命令行参数传递给该对象。接着, `Command` 对象使用 `_parse_args()` 函数解析命令行参数。`Command` 对象根据解析后的参数调用相应的命令。
|
|
|
|
|
|
|
|
|
|
4.帮助文档生成
|
|
|
|
|
|
|
|
|
|
fire的帮助文本由helptext模块的HelpText类生成 , `HelpText` 类收集命令信息并生成帮助文本,包括命令名称、描述、参数、选项和示例
|
|
|
|
|
|
|
|
|
|
![image-20240427154637648](C:\Users\86135\AppData\Roaming\Typora\typora-user-images\image-20240427154637648.png)
|
|
|
|
|
|
|
|
|
|
在这段代码里,函数创建了几个组件的信息,例如name_section、synopsis_section、description_section等等,将各个部分格式化为字符串,并通过换行符连接起来,生成最终的详细信息字符串。
|