繁体   English   中英

Python 3 导入钩子

[英]Python 3 import hooks

我正在尝试在 Python 3 中实现一个“导入钩子”。该钩子应该为每个导入的类添加一个属性。 (不是每个班级,但为了简化问题,我们假设如此。)

我有一个加载器定义如下:

import sys

class ConfigurableImports(object):

    def find_module(self, fullname, path):
        return self

    def create_module(self, spec):
        # ???

    def exec_module(self, module):
        # ???

sys.meta_path = [ConfigurableImports()]

该文件指出,为3.6,装载机将不得不同时实现create_moduleexec_module 但是,文档也几乎没有说明应该如何实现这些,也没有示例。 我的用例非常简单,因为我只加载 Python 模块,加载器的行为应该与默认行为几乎完全相同。

如果可以,我只使用importlib.import_module然后相应地修改模块内容; 然而,由于 importlib 利用了 import 钩子,我得到了无限递归。

编辑:我也尝试过使用imp模块的load_module ,但这已被弃用。

有没有什么简单的方法可以用导入钩子实现这个功能,还是我用错误的方式来实现这个功能?

恕我直言,如果您只需要更改模块,即在找到并加载后使用它,则无需实际创建一个完整的钩子来查找、加载和返回模块; 只需修补__import__

这可以通过几行轻松完成:

import builtins 
from inspect import getmembers, isclass

old_imp = builtins.__import__

def add_attr(mod):
    for name, val in getmembers(mod):
        if isclass(val):
            setattr(val, 'a', 10)

def custom_import(*args, **kwargs):
    m = old_imp(*args, **kwargs)
    add_attr(m)
    return m

builtins.__import__ = custom_import

在这里, __import__被您的自定义导入替换,该导入调用原始__import__以获取加载的模块,然后调用一个函数add_attr ,该函数在返回模块之前对模块中的类(使用getmembersisclass进行inspect )进行实际修改。

当然,这是以在import脚本时进行更改的方式创建的。

如果需要,您可以并且可能应该创建辅助功能来restore和更改它,例如:

def revert(): builtins.__import__ = old_imp

def apply(): builtins.__import__ = custom_import

上下文管理器也会使这个实现更清晰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM