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

如何为自定义pip包my_package实现可选功能扩展?

主包与可选扩展包的联动实现方案

一、配置可选依赖(pyproject.toml)

先在主包my_package的pyproject.toml中配置可选依赖组,将扩展包关联到对应组,用户执行pip install my_package[extra1]时会自动安装主包及对应扩展:

[project]
name = "my_package"
version = "0.1.0"

[project.optional-dependencies]
extra1 = ["my_package_extra1>=0.1.0"]
extra2 = ["my_package_extra2>=0.1.0"]

二、主包调用扩展功能的两种优雅方式

1. 动态导入+异常捕获(简单场景)

主包无需提前硬编码扩展包路径,在需要使用扩展功能的位置,通过捕获ImportError判断扩展是否安装,存在则导入使用,不存在则给出明确提示:

# my_package/core.py
def use_extra1_feature():
    try:
        from my_package_extra1 import extra1_core_func
        return extra1_core_func()
    except ImportError:
        raise RuntimeError(
            "需安装对应扩展才可使用该功能:执行 pip install my_package[extra1]"
        )

2. 入口点自动注册(复杂多扩展场景)

如果希望新增扩展时主包无需修改代码,可利用Python的入口点机制实现解耦式自动发现:

步骤1:扩展包配置入口点

在my_package_extra1的pyproject.toml中,将扩展类注册到主包指定的入口点组:

[project.entry-points."my_package.extensions"]
extra1 = "my_package_extra1:Extra1Extension"

步骤2:扩展包实现功能类

# my_package_extra1/__init__.py
class Extra1Extension:
    @staticmethod
    def execute():
        return "运行extra1扩展的核心功能"

步骤3:主包扫描加载扩展

主包通过importlib.metadata(Python 3.8+)扫描所有已注册的入口点,自动加载可用扩展:

# my_package/extension_manager.py
import importlib.metadata

def load_all_extensions():
    extensions = {}
    # 扫描指定组的所有入口点
    for entry in importlib.metadata.entry_points().select(group="my_package.extensions"):
        try:
            ext_cls = entry.load()
            extensions[entry.name] = ext_cls
        except ImportError:
            continue
    return extensions

# 使用示例
loaded_exts = load_all_extensions()
if "extra1" in loaded_exts:
    result = loaded_exts["extra1"].execute()
    print(result)
else:
    print("extra1扩展未安装")

三、关于依赖检测的必要性

必须做依赖检测,因为用户可能仅安装主包未装扩展。两种场景对应不同检测方式:

  • 简单场景用ImportError捕获:直接、直观,适合单个扩展的调用逻辑。
  • 多扩展场景用入口点扫描:无需硬编码扩展包名称,新增扩展时主包无需改动,扩展性更强。

额外实践建议

  • 扩展包命名尽量与主包关联,比如my_package_extra1或my_package-extra1,方便用户识别归属。
  • 在主包README中明确标注各extra组对应的功能,比如[extra1]对应大数据处理扩展、[extra2]对应可视化扩展。
  • 可在主包中添加命令行工具,帮助用户快速查看已安装扩展:
# my_package/cli.py
import click
from .extension_manager import load_all_extensions

@click.command()
def list_extensions():
    exts = load_all_extensions()
    if exts:
        click.echo("已安装扩展列表:")
        for name in exts:
            click.echo(f"- {name}")
    else:
        click.echo("当前未安装任何扩展")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:20:54