10.12 导入模块的同时修改模块

    这里问题的本质就是你想在模块被加载时执行某个动作。可能是你想在一个模块被加载时触发某个回调函数来通知你。

    这个问题可以使用10.11小节中同样的导入钩子机制来实现。下面是一个可能的方案:

    这样,你就可以使用 装饰器了,例如:

    本节技术依赖于10.11小节中讲述过的导入钩子,并稍作修改。

    装饰器的作用是注册在导入时被激活的处理器函数。该装饰器检查sys.modules来查看模块是否真的已经被加载了。如果是的话,该处理器被立即调用。不然,处理器被添加到 _post_import_hooks 字典中的一个列表中去。 的作用就是收集所有的为每个模块注册的处理器对象。一个模块可以注册多个处理器。

    要让模块导入后触发添加的动作,PostImportFinder 类被设置为sys.meta_path第一个元素。它会捕获所有模块导入操作。

    当一个模块被 加载后,所有在_post_import_hooks被注册的处理器被调用,使用新加载模块作为一个参数。

    有一点需要注意的是本机不适用于那些通过 imp.reload() 被显式加载的模块。也就是说,如果你加载一个之前已被加载过的模块,那么导入处理器将不会再被触发。另外,要是你从sys.modules中删除模块然后再重新导入,处理器又会再一次触发。

    更多关于导入后钩子信息请参考 PEP 369.