前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python pluggy框架基础用法总结

Python pluggy框架基础用法总结

作者头像
授客
发布2021-06-29 09:59:59
6960
发布2021-06-29 09:59:59
举报
文章被收录于专栏:授客的专栏

代码为例进行说明

实践环境

Python 3.6.5

pluggy 0.13.0

例1 注册类函数为插件函数

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pluggy

hookspec = pluggy.HookspecMarker("myproject")  # hook 标签 用于标记hook
hookimpl = pluggy.HookimplMarker("myproject")  # hook 实现标签 用于标记hook的一个或多个实现


class MySpec(object):
    """hook 集合"""

    @hookspec
    def myhook(self, arg1, arg2):
        pass

    @hookspec
    def my_hook_func1(self, arg1, arg2):
        pass

    @hookspec
    def my_hook_func2(self, arg1, arg2):
        pass

# 插件类
class Plugin_1(object):
    """hook实现类1"""

    @hookimpl
    def myhook(self, arg1, arg2):
        print("Plugin_1.myhook called")
        return arg1 + arg2

    @hookimpl
    def my_hook_func2(self, arg1, arg2):
        print("Plugin_1.my_hook_func2 called, args:", arg1, arg2)

    def my_hook_func3(self, arg1, arg2):
        print("Plugin_1.my_hook_func3 called, args:", arg1, arg2)


class Plugin_2(object):
    """hook实现类2"""

    @hookimpl
    def myhook(self, arg1, arg2):
        print("Plugin_2.myhook called")
        return arg1 - arg2

    @hookimpl
    def my_hook_func2(self, arg1, arg2):
        print("Plugin_2.my_hook_func2, args:", arg1, arg2)

# 初始化 PluginManager
pm = pluggy.PluginManager("myproject")

# 登记hook集合(hook函数声明)
pm.add_hookspecs(MySpec)

# 注册插件(hook函数实现)
pm.register(Plugin_1())
pm.register(Plugin_2())

# 调用自定义hook
results = pm.hook.myhook(arg1=1, arg2=2) # 调用两个插件类中的同名hook函数 # 后注册的插件中的函数会先被调用
print(results) # 输出 [-1, 3]

results = pm.hook.my_hook_func1(arg1="name", arg2="shouke")
print(results)

pm.hook.my_hook_func2(arg1="addr", arg2="sz")

运行结果

代码语言:javascript
复制
Plugin_2.myhook called
Plugin_1.myhook called
[-1, 3]
[]
Plugin_2.my_hook_func2, args: addr sz
Plugin_1.my_hook_func2 called, args: addr sz

例2 注册模块函数为插件函数

myhookspec.pymyhookimpl.pyother.pyexample.py位于同一包目录下

myhookspec.py

代码语言:javascript
复制
import pluggy

hookspec = pluggy.HookspecMarker("myproject")  # hook 标签 用于标记hook
hookimpl = pluggy.HookimplMarker("myproject")  # hook 实现标签 用于标记hook的一个或多个实现

@hookspec
def global_hook_func1(arg1, arg2):
    pass

myhookimpl.py

代码语言:javascript
复制
import pluggy

from myhookspec import hookimpl

@hookimpl
def global_hook_func1(arg1, arg2):
    print("global_hook_func1 in myhookimpl.py, args:", arg1, arg2)
    return "myhookimpl.py"

other.py

代码语言:javascript
复制
from myhookspec import hookimpl

@hookimpl
def global_hook_func1(arg1, arg2):
    print("global_hook_func1 in other.py, args:", arg1, arg2)
    return "other.py"

example.py

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import sys
import pluggy
import myhookspec
import myhookimpl
import other

# 初始化 PluginManager
pm = pluggy.PluginManager("myproject")

# 登记hook集合
pm.add_hookspecs(myhookspec)

# 登记hook的实现
pm.register(myhookimpl) # 插件也可以是模块
pm.register(other)

print(pm.hook.global_hook_func1(arg1="name", arg2="shouke"))

example.py运行结果如下

代码语言:javascript
复制
global_hook_func1 in other.py, args: name shouke
global_hook_func1 in myhookimpl.py, args: name shouke
['other.py', 'myhookimpl.py']

例3:自定义插件类实现hook函数免@hookimpl装饰器

myhookspec.py

代码语言:javascript
复制
import pluggy

hookspec = pluggy.HookspecMarker("myproject")

@hookspec
def mytest_hook_func1(arg1, arg2):
    pass

other.py

代码语言:javascript
复制
def mytest_hook_func1(arg1, arg2):
    print("global_hook_func1 in other.py, args:", arg1, arg2)
    return "other.py"

example.py

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import inspect
import pluggy
import myhookspec
import other


class PytestPluginManager(pluggy.PluginManager):
    """
    插件类,实现不用@HookimplMarkerInstance装饰的函数也可以当做函数体
    """

    def parse_hookimpl_opts(self, plugin, name):
        # 规定免@hookimpl装饰的 hooks 函数总是以 mytest_打头,这样以避免访问非可读属性

        if not name.startswith("mytest_"):
            return

        method = getattr(plugin, name)
        opts = super().parse_hookimpl_opts(plugin, name)

        # 考虑hook只能为函数(consider only actual functions for hooks)
        if not inspect.isroutine(method):
            return

        # 收集未被标记的,以mytest打头的hook函数,(collect unmarked hooks as long as they have the `pytest_' prefix)
        if opts is None and name.startswith("mytest_"):
            opts = {}
        return opts


# 初始化 PluginManager
pm = PytestPluginManager("myproject")

# 登记hook集合
pm.add_hookspecs(myhookspec)

# 登记hook的实现
pm.register(other)

pm.hook.mytest_hook_func1(arg1="addr", arg2="sz")

参考连接

https://pypi.org/project/pluggy/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实践环境
  • 例1 注册类函数为插件函数
  • 例2 注册模块函数为插件函数
    • myhookspec.py
      • myhookimpl.py
        • other.py
          • example.py
          • 例3:自定义插件类实现hook函数免@hookimpl装饰器
            • myhookspec.py
              • other.py
                • example.py
                • 参考连接
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档