为何inspect无法获取动态导入模块中类的源文件信息?
问题解决:动态导入模块后无法获取类的源信息
当使用importlib.util动态导入模块时,你会发现inspect模块能正常获取函数的源文件和源代码,但对类调用inspect.getsourcefile()或inspect.getsource()时,会抛出TypeError,提示类是"built-in class",就像你遇到的情况一样。
问题原因
这是因为你用importlib.util.module_from_spec()创建模块后,没有将该模块注册到sys.modules字典中。inspect模块在判断类的来源时,会依赖模块在sys.modules中的注册信息,未注册的模块会让inspect无法正确识别类的实际来源文件,从而误判为内置类。
解决方案
在执行spec.loader.exec_module(module)之后,将导入的模块添加到sys.modules中即可。
修改后的thing1.py代码如下:
import inspect import os import importlib.util import sys # 新增导入sys模块 dir_here = os.path.dirname(__file__) spec = importlib.util.spec_from_file_location("thing2", os.path.join(dir_here, "thing2.py")) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) sys.modules["thing2"] = module # 新增:将模块注册到sys.modules print(module.foo(3)) print(module.Bar().inc(3)) print("module source file:", inspect.getsourcefile(module)) for attr in ['foo','Bar']: print("%s source: %s" % (attr, inspect.getsourcefile(getattr(module, attr)))) print(inspect.getsource(getattr(module, attr)))
运行结果
修改后运行thing1.py,就能正常获取类的源信息了:
> python c:\tmp\python\test2\thing1.py 4 4 module source file: c:\tmp\python\test2\thing2.py foo source: c:\tmp\python\test2\thing2.py def foo(x): return x+1 Bar source: c:\tmp\python\test2\thing2.py class Bar(object): def inc(self, x): return x+1
内容的提问来源于stack exchange,提问作者Jason S
相关产品推荐
相关产品推荐

