Monkey patch就是在运行时对已有的代码进行修改,达到hot patch的目的!
python namespace
locals
globals
builtin
其中定义在函数内声明的变量属于locals,而模块内定义的函数属于globals。
Python module Import
当我们import一个module时,python会做以下几件事情
导入一个module
将module对象加入到sys.modules,后续对该module的导入将直接从该dict中获得
将module对象加入到globals dict中
当我们引用一个模块时,将会从globals中查找。这里如果要替换掉一个标准模块,我们得做以下两件事情
将我们自己的module加入到sys.modules中,替换掉原有的模块。如果被替换模块还没加载,那么我们得先对其进行加载,否则第一次加载时,还会加载标准模块。
(这里有一个import hook可以用,不过这需要我们自己实现该hook,可能也可以使用该方法hook module import)
如果被替换模块引用了其他模块,那么我们也需要进行替换,但是这里我们可以修改globals() dict,将我们的module加入到globals以hook这些被引用的模块。
1. import 实际上是python虚拟机把当前的globals()和locals()传进__builtins__.__import__内置函数了,所以实际上干活的是那个__import__函数!
2. import对命名空间的影响
1)如果是python的内置模块,例如os模块。这些模块是随着python虚拟机启动而加载进来的,但是并没有暴露出来。我们可以通过dir()命令查看当前命名空间
通过sys.modules这个字典(key: 模块名;value: 模块的路径),我们可以查看模块的信息
2) import只影响当前模块的命名空间
3. import package
首先合法的package必须含有一个__init__.py文件,package可以包含0个或多个module(py文件).
import packtest.sub.b __init__.py文件的内容第一次导入是输出。
print sys.modues
4 from与import