我正在寻找一种动态修饰功能的方法,最好是在导入时。这个想法是建立一个配置,允许我在导入模块时装饰功能。
我已经尝试挂钩到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())