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

如何在运行时添加entry points以被importlib.metadata.entry_points()识别?

运行时添加Entry Point并让importlib.metadata识别的方法

importlib.metadata依赖已安装包的dist-info目录结构加载entry points,要在运行时动态添加,有两种可行方案:

方案1:创建临时dist-info目录(推荐,兼容性好)

这种方法完全遵循importlib.metadata的原生加载逻辑,无需依赖私有API:

import sys
import tempfile
import os
from importlib.metadata import entry_points

# 创建临时目录存放自定义分发信息
with tempfile.TemporaryDirectory() as tmpdir:
    # 构建合法的dist-info目录结构
    dist_info_path = os.path.join(tmpdir, "my_custom_pkg-0.0.1.dist-info")
    os.makedirs(dist_info_path)

    # 写入entry points配置
    with open(os.path.join(dist_info_path, "entry_points.txt"), "w") as f:
        f.write("""[my_entry_group]
my_custom_entry = my_module:my_function
""")

    # 写入必填的METADATA文件
    with open(os.path.join(dist_info_path, "METADATA"), "w") as f:
        f.write("Name: my_custom_pkg\nVersion: 0.0.1\n")

    # 将临时目录加入sys.path,让importlib.metadata能发现它
    sys.path.insert(0, tmpdir)

    # 验证结果
    entries = entry_points().get("my_entry_group", [])
    print([ep.name for ep in entries])  # 输出: ['my_custom_entry']

如果你的my_module不在默认搜索路径里,记得把它所在目录也加入sys.path,否则调用ep.load()会失败。

方案2:直接注入自定义分发对象(依赖内部API,需注意版本兼容)

如果你能接受依赖importlib.metadata的内部私有属性,可以直接创建分发对象并注入缓存:

import importlib.metadata
from importlib.metadata import EntryPoint, Distribution

# 定义自定义entry point
custom_ep = EntryPoint(
    name="my_custom_entry",
    value="my_module:my_function",
    group="my_entry_group"
)

# 拿一个已存在的分发对象作为模板(也可以完全自定义)
existing_dist = next(importlib.metadata.distributions())
# 构造包含自定义entry point的分发对象
custom_dist = Distribution(
    existing_dist._path,
    metadata=existing_dist.metadata,
    entry_points={"my_entry_group": [custom_ep]}
)

# 注入到分发缓存(不同Python版本的缓存属性可能不同,这里适配3.10-3.12)
if hasattr(importlib.metadata, "_distributions"):
    importlib.metadata._distributions.append(custom_dist)
else:
    # 新版本可能需要清空_get_distributions的缓存
    from importlib.metadata import _get_distributions
    _get_distributions.cache_clear()
    # 也可以配合sys.path添加临时目录,不过上面的方式更直接

# 验证
entries = importlib.metadata.entry_points().get("my_entry_group", [])
print([ep.name for ep in entries])  # 输出: ['my_custom_entry']

这种方法的缺点是私有API可能随Python版本变更,升级后需要调整代码。

内容的提问来源于stack exchange,提问作者flying sheep

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 17:52:32