如何在Python的pluggy中实现支持任意参数的Hook?
解决Pluggy框架Hook接收可变参数的调用错误
在使用Pluggy开发插件时,若Hook定义为接收任意数量的位置参数(*arg),直接通过self.pm.hook.method(*arg)调用会触发类型错误,提示HookCaller的__call__方法仅接受1个位置参数但传入了多个。
错误信息
File "my_file.py", line 36, in run self.pm.hook.method(*arg) TypeError: HookCaller.__call__() takes 1 positional argument but 3 were given
解决方案
方法1:修改Hook Spec,允许位置参数传递
Pluggy默认要求钩子调用使用关键字参数,若要兼容位置参数传递,需在@hookspec装饰器中添加historic=True参数:
class Spec: @hookspec(historic=True) def method(self, *arg): """The method hook """ pass
修改后原调用代码self.pm.hook.method(*arg)即可正常执行,插件中的*arg会正确接收传入的所有参数(如示例中的(1, 2))。
方法2:通过关键字参数传递可变参数
若不想调整hookspec配置,可将可变参数打包为关键字参数传递,同时修改插件的参数接收逻辑:
- 修改App类的
run方法:
def run(self, *arg): self.pm.hook.method(args=arg)
- 修改Plugin类的
method方法:
@hookimpl(specname="method") def method(self, args): print("Plugin method called with", args)
这种方式会把所有传入的参数打包成一个元组,通过args关键字参数传递给Hook,插件直接处理该元组即可。
内容的提问来源于stack exchange,提问作者Maxi mini
相关产品推荐
相关产品推荐

