Version: 2.0.0rc4

插件编写准备

在正式编写插件之前,我们需要先了解一下插件的概念。

插件结构

在 NoneBot 中,插件即是 Python 的一个模块(module)。NoneBot 会在导入时对这些模块做一些特殊的处理使得他们成为一个插件。插件间应尽量减少耦合,可以进行有限制的相互调用,NoneBot 能够正确解析插件间的依赖关系。

单文件插件

一个普通的 .py 文件即可以作为一个插件,例如创建一个 foo.py 文件:

Project
📂 plugins
└── 📜 foo.py

这个时候模块 foo 已经可以被称为一个插件了,尽管它还什么都没做。

包插件

一个包含 __init__.py 的文件夹即是一个常规 Python package,例如创建一个 foo 文件夹:

Project
📂 plugins
└── 📂 foo
└── 📜 __init__.py

这个时候包 foo 同样是一个合法的插件,插件内容可以在 __init__.py 文件中编写。

创建插件

注意

如果在之前的快速上手章节中已经使用 bootstrap 模板创建了项目,那么你需要做出如下修改:

  1. 在项目目录中创建一个两层文件夹 awesome_bot/plugins

    Project
    📦 awesome-bot
    ├── 📂 awesome_bot
    │ └── 📂 plugins
    ├── 📜 pyproject.toml
    └── 📜 README.md
  2. 修改 pyproject.toml 文件中的 nonebot 配置项,在 plugin_dirs 中添加 awesome_bot/plugins

    pyproject.toml
    [tool.nonebot]
    plugin_dirs = ["awesome_bot/plugins"]
注意

如果在之前的创建项目章节中手动创建了相关文件,那么你需要做出如下修改:

  1. 在项目目录中创建一个两层文件夹 awesome_bot/plugins

    Project
    📦 awesome-bot
    ├── 📂 awesome_bot
    │ └── 📂 plugins
    └── 📜 bot.py
  2. 修改 bot.py 文件中的加载插件部分,取消注释或者添加如下代码

    bot.py
    # 在这里加载插件
    nonebot.load_builtin_plugins("echo") # 内置插件
    nonebot.load_plugins("awesome_bot/plugins") # 本地插件

创建插件可以通过 nb-cli 命令从完整模板创建,也可以手动新建空白文件。通过以下命令创建一个名为 weather 的插件:

$ nb plugin create
[?] 插件名称: weather
[?] 使用嵌套插件? (y/N) N
[?] 输出目录: awesome_bot/plugins

nb-cli 会在 awesome_bot/plugins 目录下创建一个名为 weather 的文件夹,其中包含的文件将在稍后章节中用到。

Project
📦 awesome-bot
├── 📂 awesome_bot
│ └── 📂 plugins
| └── 📂 foo
| ├── 📜 __init__.py
| └── 📜 config.py
├── 📜 pyproject.toml
└── 📜 README.md

加载插件

警告

请勿在插件被加载前 import 插件模块,这会导致 NoneBot 无法将其转换为插件而出现意料之外的情况。

加载插件是在机器人入口文件中完成的,需要在框架初始化之后,运行之前进行。

请注意,加载的插件模块名称(插件文件名或文件夹名)不能相同,且每一个插件只能被加载一次,重复加载将会导致异常。

如果你使用 nb-cli 管理插件,那么你可以跳过这一节,nb-cli 将会自动处理加载。

如果你使用自定义的入口文件 bot.py,那么你需要在 bot.py 中加载插件。

bot.py
import nonebot

nonebot.init()

# 加载插件

nonebot.run()

加载插件的方式有多种,但在底层的加载逻辑是一致的。以下是为加载插件提供的几种方式:

load_plugin

通过点分割模块名称或使用 pathlibPath 对象来加载插件。通常用于加载第三方插件或者项目插件。例如:

from pathlib import Path

nonebot.load_plugin("path.to.your.plugin") # 加载第三方插件
nonebot.load_plugin(Path("./path/to/your/plugin.py")) # 加载项目插件
注意

请注意,本地插件的路径应该为相对机器人 入口文件(通常为 bot.py) 可导入的,例如在项目 plugins 目录下。

load_plugins

加载传入插件目录中的所有插件,通常用于加载一系列本地编写的项目插件。例如:

nonebot.load_plugins("src/plugins", "path/to/your/plugins")
注意

请注意,插件目录应该为相对机器人 入口文件(通常为 bot.py) 可导入的,例如在项目 plugins 目录下。

load_all_plugins

这种加载方式是以上两种方式的混合,加载所有传入的插件模块名称,以及所有给定目录下的插件。例如:

nonebot.load_all_plugins(["path.to.your.plugin"], ["path/to/your/plugins"])

load_from_json

通过 JSON 文件加载插件,是 load_all_plugins 的 JSON 变种。通过读取 JSON 文件中的 plugins 字段和 plugin_dirs 字段进行加载。例如:

plugin_config.json
{
"plugins": ["path.to.your.plugin"],
"plugin_dirs": ["path/to/your/plugins"]
}
nonebot.load_from_json("plugin_config.json", encoding="utf-8")
提示

如果 JSON 配置文件中的字段无法满足你的需求,可以使用 load_all_plugins 方法自行读取配置来加载插件。

load_from_toml

通过 TOML 文件加载插件,是 load_all_plugins 的 TOML 变种。通过读取 TOML 文件中的 [tool.nonebot] Table 中的 pluginsplugin_dirs Array 进行加载。例如:

plugin_config.toml
[tool.nonebot]
plugins = ["path.to.your.plugin"]
plugin_dirs = ["path/to/your/plugins"]
nonebot.load_from_toml("plugin_config.toml", encoding="utf-8")
提示

如果 TOML 配置文件中的字段无法满足你的需求,可以使用 load_all_plugins 方法自行读取配置来加载插件。

load_builtin_plugin

加载一个内置插件,传入的插件名必须为 NoneBot 内置插件。该方法是 load_plugin 的封装。例如:

nonebot.load_builtin_plugin("echo")

load_builtin_plugins

加载传入插件列表中的所有内置插件。例如:

nonebot.load_builtin_plugins("echo", "single_session")

其他加载方式

有关其他插件加载的方式,可参考跨插件访问嵌套插件