前言
本篇将详细对plugin的注册逻辑进行分析
个人拙见,有错请各位指出。
如果的我的文章对您有帮助,不符动动您的金手指给个Star,予人玫瑰,手有余香,不胜感激。 GitHub
pluggy注册逻辑分析性
我们来详细分析一下plugin的注册逻辑register方法
下面以分片段的形式呈现
plugin_name = name or self.get_canonical_name(plugin) #获取插件名
if plugin_name in self._name2plugin or plugin in self._plugin2hookcallers:
if self._name2plugin.get(plugin_name, -1) is None:
return # blocked plugin, return None to indicate no registration
raise ValueError(
"Plugin already registered: %s=%s\n%s"
% (plugin_name, plugin, self._name2plugin)
)
- 根据传入plugin name或由plugin对象获取到插件名,将其赋值给plugin_name
- self._name2plugin是以plugin_name为key的dict
- self._pluginhookcallers是以plugin object为key的dict
- 通过上述两个dict来判断传入的plugin是否已经注册过了
self._name2plugin[plugin_name] = plugin
- 将这个pluggy以
plugin_name:plugin object
的形式保存到self._name2plugin
中
self._plugin2hookcallers[plugin] = hookcallers = []
- 创建一个
list
对象hookcallers
用来保存每个pluggy的实际调用对象_HookCaller
,以plugin object:hookcallers object
的形式保存在self._plugin2hookcallers
for name in dir(plugin):
hookimpl_opts = self.parse_hookimpl_opts(plugin, name) #获取pluggy的属性或方法中的特殊attribute project_name + _impl
if hookimpl_opts is not None:
normalize_hookimpl_opts(hookimpl_opts)
method = getattr(plugin, name) #特殊attribute存在时获取到plugin的对应方法
hookimpl = HookImpl(plugin, plugin_name, method, hookimpl_opts)
hook = getattr(self.hook, name, None)