You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取已加载文件路径列表及曾加载后移除的模块路径?

如何追踪所有曾加载过的模块文件路径

好问题!你当前用sys.modules配合inspect.getfile()的方法,确实能拿到当前活跃模块的文件路径,但要覆盖那些加载后又从sys.modules中移除的模块,就得从Python的模块加载机制入手——毕竟sys.modules只是当前模块的缓存,模块被删除后这里就没有留存记录了。

下面分享两种可行的思路:

1. 提前Hook模块加载流程(推荐方案)

Python的模块加载是通过sys.meta_path里的查找器(Finder)和加载器(Loader)完成的,我们可以自定义一个追踪器,插入到这个流程里,在模块加载的瞬间就记录下它的文件路径,这样哪怕之后模块被从sys.modules中移除,我们的记录依然保留。

示例代码如下:

import sys
import importlib.abc
import importlib.util

class ModuleLoadTracker(importlib.abc.MetaPathFinder, importlib.abc.Loader):
    def __init__(self):
        self.loaded_files = set()
        # 初始化时先记录当前已加载的所有非内置模块路径
        for module in sys.modules.values():
            try:
                if hasattr(module, '__file__') and module.__file__ is not None:
                    self.loaded_files.add(module.__file__)
            except Exception:
                # 跳过无法获取路径的模块(比如部分特殊内置模块)
                pass

    def find_spec(self, fullname, path, target=None):
        # 先让默认的查找器处理模块查找,我们只负责记录路径
        spec = None
        for finder in sys.meta_path:
            if finder is self:
                continue
            try:
                spec = finder.find_spec(fullname, path, target)
                if spec is not None:
                    break
            except Exception:
                continue
        # 记录有效模块的源文件路径(排除内置模块)
        if spec and spec.origin is not None and spec.origin != 'built-in':
            self.loaded_files.add(spec.origin)
        return spec

# 初始化追踪器并插入到meta_path最前面,确保能拦截所有加载请求
tracker = ModuleLoadTracker()
sys.meta_path.insert(0, tracker)

使用说明:

  • 把这段代码放在你程序的最开头运行,这样就能从程序启动时开始追踪所有模块加载。
  • 之后不管你加载、删除多少模块,所有曾被加载过的文件路径都会存在tracker.loaded_files这个集合里(自动去重)。
  • 注意过滤掉了内置模块(它们没有物理文件路径),以及一些无法获取路径的特殊模块。

2. 事后补救:无法追踪已移除的模块

如果是程序已经运行了一段时间,现在才想到要追踪已加载过的模块,那很遗憾——Python本身不会默认保存已移除模块的加载历史,sys.modules里已经没有这些模块的痕迹,也就无法回溯它们的文件路径了。这种情况下只能通过上面的Hook方案,在后续的代码运行中做追踪。

补充:你原有方法的局限性

你之前的代码:

import inspect
import sys
lizard = list()
for mdl in sys.modules.values():
    try:
        lizard.append(inspect.getfile(mdl))
    except:
        pass

只能获取当前存在于sys.modules中的模块,如果模块被通过del sys.modules["module_name"]移除,或者被Python的垃圾回收机制清理,这段代码就拿不到对应的路径了。

内容的提问来源于stack exchange,提问作者Toothpick Anemone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:24:55