如何获取 importlib 导入的模块的路径,其中定义了 class

How to get a path for a module imported by importlib, where a class was defined

有一个很好的方法可以为定义了 class 的模块获取路径,只需执行

inspect.getfile(obj.__class__)

不幸的是,它似乎因 importlib 加载的文件而崩溃:

spec = importlib.util.spec_from_file_location('loaded_module', module_path)
M = importlib.util.module_from_spec(spec)
spec.loader.exec_module(M)

obj = M.MyClass()
inspect.getfile(obj.__class__)

结果

  File "/nix/store/z65l1jqvxa58zzwwa3bvglb6asj4y8cv-python3-3.8.5/lib/python3.8/inspect.py", line 665, in getfile
    raise TypeError('{!r} is a built-in class'.format(object))
TypeError: <class 'loaded_module.MyClass'> is a built-in class

有什么解决办法吗?

inspect.getfile 的期望是 class 对象(它有一个字符串 __module__ 属性,它是模块名称)在 sys.modules 中有它的模块(其中可以通过名称查找模块)

如果没有 sys.modules 中的模块,它无法使用该链来查找您的文件

将它放入 sys.modules 你会做这样的事情:

sys.modules[M.__name__] = M

但是如果您有权访问某处的 M 对象,则可以直接访问 .__file__,或者如果您有权访问 loader

或者,如果您知道在该文件的 class 上定义了某些方法,您可以查询该函数的代码对象:

>>> M.C.__init__.__code__.co_filename
t.py