gpt4 book ai didi

Python 3 导入 Hook

转载 作者:太空宇宙 更新时间:2023-11-03 11:22:48 27 4
gpt4 key购买 nike

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

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

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 利用导入 Hook ,我得到了无限递归。

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

是否有任何简单的方法可以使用导入 Hook 来实现此功能,还是我的做法有误?

最佳答案

恕我直言,如果您只需要更改模块,即在找到并加载模块后使用它,则无需实际创建用于查找、加载和返回模块的完整 Hook ;只需修补 __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在返回模块之前对模块中的类进行实际修改(使用 inspect 中的 getmembersisclass)。

当然,这是在您导入 脚本时进行更改的方式创建的。

您可以并且可能应该创建辅助函数来恢复并在需要时再次更改它,例如:

def revert(): builtins.__import__ = old_imp

def apply(): builtins.__import__ = custom_import

上下文管理器也会让这个实现更简洁。

关于Python 3 导入 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39418845/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com