我想实现一个自定义的 Python 模块加载器,如here所述。这个过程看起来非常简单,除了我不知道如何最终委托给默认加载过程,我想在实现时我想要这样做
exec_module
。
例如,我可以将这个“Finder”放在
sys.meta_path
上,当我import
模块时它会被调用。
import sys
import importlib.machinery
import types
class Finder:
def find_spec(name, path, target):
print(f"find_spec: {name}, path={path}, target={target}")
if not name.startswith('my_prefix.'):
return None
return importlib.machinery.ModuleSpec(name, Finder, is_package=True)
def create_module(spec):
print(f"create_module, spec = {spec}")
mod = types.ModuleType(spec.name)
return mod
def exec_module(mod):
print(f"exec_module, mod = {mod}")
# How to use a file here, to define the module?
mod.test = 123
sys.meta_path.append(Finder)
import my_prefix.foo
这三个函数按预期被调用。现在假设我想加载某个文件来定义大部分
my_prefix.foo
模块。我如何在exec_module
内做到这一点?我是否手动从文件中读取代码并调用内置的 exec 函数?或者在定义模块时有更好的方法吗?
根据文档:https://docs.python.org/3/library/importlib.html
你不应该在你的
Finder
类中实现 find_spec 。它看起来就像一个Loader
类。也许你应该实现你自己的类继承形式importlib.abc.PathEntryFinder
。
附注这不是答案,但由于声誉限制,我无法写评论。