如何在导入时动态导入功能

时间:2020-07-20 14:54:21

标签: python python-3.x

我正在寻找一种动态修饰功能的方法,最好是在导入时。这个想法是建立一个配置,允许我在导入模块时装饰功能。

我已经尝试挂钩到importlib,并且可以获取导入模块时要执行的代码。下面的代码可以执行此操作,但不会在每次导入时触发。激活代码后(通过将MyMetaFinder类放置在sys.meta_path中),某些导入不会触发加载程序。

class MyMetaFinder(MetaPathFinder):
    def find_spec(self, fullname, path, target=None):
        print(f"II: Finding spec for {fullname} in {path}")
        if path is None or path == "":
            path = [os.getcwd()]  # top level import --
        if "." in fullname:
            *parents, name = fullname.split(".")
        else:
            name = fullname
        for entry in path:
            if os.path.isdir(os.path.join(entry, name)):
                # this module has child modules
                filename = os.path.join(entry, name, "__init__.py")
                submodule_locations = [os.path.join(entry, name)]
            else:
                filename = os.path.join(entry, name + ".py")
                submodule_locations = None
            if not os.path.exists(filename):
                continue

            return spec_from_file_location(
                fullname,
                filename,
                loader=MyLoader(filename),
                submodule_search_locations=submodule_locations,
            )
        return None  # we don't know how to import this


class MyLoader(Loader):
    def __init__(self, filename):
        self.filename = filename

    def create_module(self, spec):
        return None  # use default module creation semantics

    def exec_module(self, module):
        print(f"II: Importing module {module.__name__}")
        with open(self.filename) as f:
            data = f.read()

        exec(data, vars(module))


def setup_instrumentation():
    print("II: Setting up instrumentation")

    sys.meta_path.insert(0, MyMetaFinder())

0 个答案:

没有答案