nonebot2/docs/advanced/export-and-require.md
2021-02-07 10:59:13 +08:00

3.5 KiB
Raw Blame History

跨插件访问

由于nonebot2独特的插件加载机制在使用python原有的import机制来进行插件之间的访问时很可能会有奇怪的或者意料以外的情况发生。为了避免这种情况的发生您可以有两种方法来实现跨插件访问

  1. 将插件间的要使用的公共代码剥离出来,作为公共文件或者文件夹,提供给插件加以调用。
  2. 使用nonebot2提供的exportrequire机制,来实现插件间的互相调用。

第一种方法比较容易理解和实现,这里不再赘述,但需要注意的是,请不要将公共文件或者公共文件夹作为插件nonebot2加载。

下面将介绍第二种方法——exportrequire机制:

使用export and require

现在,假定有两个插件pluginApluginB,需要在pluginB中调用pluginA中的一个变量varA和一个函数funcA

在上面的条件中涉及到了两种操作:一种是在pluginA导出对象操作;而另一种是在pluginB导入对象操作。在nonebot2中,导出对象的操作用export机制来实现,导入对象的操作用require机制来实现。下面,我们将逐一进行介绍。

:::warning 警告

使用这个方法进行跨插件访问时,需要先加载导出对象的插件,再加载导入对象的插件。

:::

使用export

pluginA中,我们调用export机制导出对象

export机制调用前,我们需要保证导出的对象已经被定义,比如:

varA = "varA"


def funcA():
    return "funcA"

在确保定义之后,我们可以从nonebot.plugin导入export()方法, export()方法会返回一个特殊的字典export

from nonebot.plugin import export


export=export()

这个字典可以用来装载导出的对象它的key是对象导出后的命名value是对象本身我们可以直接创建新的key-value对导出对象:

export.vA = varA
export.fA = funcA

除此之外也支持 `嵌套` 导出对象

```python
export.sub.vA = varA
export.sub.fA = funcA
特别地对于`函数对象`而言`export`支持用`装饰器`的方法来导出因此我们可以这样定义`funcA`

```python
@export.sub
def funcA():
	return "funcA"

或者:

@export
def funcA():
	return "funcA"

通过装饰器的方法导出函数时,命名固定为函数的命名,也就是说,上面的两个例子等同于:

export.sub.funcA = funcA

export.funcA = funcA

这样,我们就成功导出varAfuncA对象了。

下面我们将介绍如何在pluginB中导入这些对象。

使用require

pluginB中,我们调用require机制导入对象

:::warning 警告

在导入来自其他插件的对象时, 请确保导出该对象的插件在引用该对象的插件之前加载。如果该插件并未被加载,则会尝试加载,加载失败则会返回 None

:::

我们可以从nonebot.plugin中导入require()方法:

from nonebot.plugin import require

require()方法的参数是插件名, 它会返回在指定插件中,用export()方法创建的字典。

require_A = require('pluginA')

在之前,这个字典已经存入了'vA'-varA, 'fA'-funcA'funcA'-funcA这样的key-value对。因此在这里我们直接用属性的方法来获取导入对象:

varA = require_A.vA
funcA = require_A.fA or require_A.funcA

这样我们就在`pluginB`中成功导入了`varA``funcA`对象了