加载模式¶
Setuptools 入口点是在定义插件代码期望的 API 的命名空间内注册的。每个入口点都有一个名称,该名称在给定的命名空间内不必唯一。这种名称管理系统的灵活性使得以各种方式使用插件成为可能。stevedore 中的管理器类包装 importlib.metadata 以应用不同的规则,以匹配此处描述的模式。
驱动程序 – 单个名称,单个入口点¶
指定用于与外部资源(数据库、设备或远程应用程序)通信的驱动程序可能是动态加载库的最常见用途。驱动程序支持资源的抽象视图,以便应用程序可以使用不同类型的资源。例如,驱动程序可以连接到数据库引擎,加载不同的文件格式,或与来自不同提供商的类似 Web 服务进行通信。对于给定的应用程序,可能有多个驱动程序可用,但应用程序和驱动程序之间的接口暗示仅使用一个驱动程序来管理给定的资源。
![digraph drivers {
app [label="namespace",shape="record"];
d1 [style=filled,color=".7 .3 1.0",label="driver 1"];
d2 [style=dotted,label="driver 2"];
d3 [style=dotted,label="driver 3"];
app -> d1;
app -> d2 [style=dotted];
app -> d3 [style=dotted];
}](../_images/graphviz-37f329b21c6097d39ea1ab1547af1143916b724c.png)
驱动程序模式的示例包括
SQLAlchemy 使用的数据库客户端库
libcloud 使用的云供应商 API 客户端
钩子 – 单个名称,多个入口点¶
钩子、信号或回调基于应用程序中发生的事件而被调用。应用程序的所有钩子可以共享单个命名空间(例如,my.application.hooks)并使用不同的名称来触发事件(例如,startup 和 precommit)。多个入口点可以在命名空间内共享相同的名称,以便在发生事件时可以调用多个钩子。
![digraph drivers {
app [label="namespace::event_name",shape="record"];
l1 [style=filled,color=".7 .3 1.0",label="event_name (lib1)"];
l2 [style=filled,color=".7 .3 1.0",label="event_name (lib2)"];
l3 [style=filled,color=".7 .3 1.0",label="event_name (lib3)"];
app -> l1;
app -> l2;
app -> l3;
}](../_images/graphviz-b5b825be30d0f85fbfa622a562bac8ce4a64dcdf.png)
钩子模式的示例包括
扩展 – 多个名称,多个入口点¶
扩展应用程序的更通用的形式是通过发现使用最小 API 在运行时注入自身的附加模块来加载其他功能。扩展通常希望在被加载和使用时得到通知,以便它们可以执行初始化或设置步骤。扩展可以替换核心功能或对其进行补充。
![digraph drivers {
app [label="application",shape="record"];
e1 [style=filled,color=".7 .3 1.0",label="extension 1"];
e2 [style=filled,color=".7 .3 1.0",label="extension 2"];
e3 [style=filled,color=".7 .3 1.0",label="extension 3"];
app -> e1;
app -> e2;
app -> e3;
}](../_images/graphviz-aa5902a1af3bfb1a459694d59f0a09981636eb9e.png)
扩展模式的示例包括