补充trace.py

mrxn27umf 5 years ago
parent ece2b6d85e
commit 7ce2edcd35

@ -3,23 +3,52 @@
它可以自动扫描module, object, class, function并自动构建管道
Expose functionality to user by archive them in a function / module / object / class / dict
# Python fire 源码分析:
## __main__.py
主要负责import被使用的module或者file将其导入Fire.fire()函数。
## trace.py
此module具有用于跟踪fire执行状况的类。
FireTrace由一系列FireTraceElement对象组成。每个元素
表示一个fire执行时的操作。一项行动可能是实例化类、调用例程或访问属性。
每个操作都使用参数并产生一个新组件。最后一部分
由Fire序列化为stdout并由Fire方法返回。如果
出现Fire用法错误例如提供的参数不足无法调用
一个函数则该Error将在trace中被capture并且final component将被设定为None。
## core.py
原型Fire(component=None, command=None, name=None).
### _Fire(component, args, parsed_flag_args, context, name=None)
这是python fire的核心部分完成fire程序的核心逻辑。几种参数含义如下
* component: 是fire构建CLI的初始元素可以是module, class, routine, object...
* args: 待component使用的参数序列
* parsed_flag_args: 启动fire的flag定制化一些fire行为
* context: 调用fire时的local和global变量
* name: 可选的名字在interactive模式使用
fire的一般执行过程如下
1. 从参数列表pop一个参数
1. 根据参数的类型
1. 实例化被使用的class
2. 或者调用命令所指向的function
3. 或者查找命令指向的属性
1. 返回步骤1
当不再能够继续执行时fire将结果序列化后输出
我们可以注意到其比较核心的功能需要用到静态代码分析、反射、模式匹配
1. 检查并处理flag(--xxx)
1. 选择当前component作为当前被处理的对象根据参数的类型
* 是class则实例化被使用的class
* 是routine则调用该routine
* 是sequence使用紧接的参数访问sequence
* 否则,尝试用紧接的属性访问该对象
* 否则如果是callable的示例调用
1. 返回上一个步骤重复直到所有args被消耗
当不再能够继续执行时fire将结果序列化后输出。
我们可以注意到其比较核心的功能需要用到代码分析技术而fire的实现如下
```
is_callable = inspect.isclass(component) or inspect.isroutine(component)
is_callable_object = callable(component) and not is_callable
is_sequence = isinstance(component, (list, tuple))
is_map = isinstance(component, dict) or inspectutils.IsNamedTuple(component)
```
其中主要使用到inspect库的各种isXXX函数。去到这个库的源文件查看可以发现如下十分方便的函数ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction() isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(), isroutine()。
再检视inspect.py文件可以发现大部分的isXXX()的实现用到了python builtins的库函数isinstance()issubclass()getattr()hasattr()...
有了python提供的这些函数就可以实现变量的动态查找和识别然后根据这些变量的不同类别进行不同的操作。
当检测到component是class, routine, callable object时调用_CallAndUpdateTrace()
Loading…
Cancel
Save