Closed SiloNeko closed 1 year ago
or you can use a getter function to wrap the bot referenced, to avoid accessing it directly
e.g.
# A.py
def get_bot() -> Bot :
...
# B.py
from A import get_bot
get_bot().sth_you_need()
Thank for your answer. But how can I easily import these modules that reference the bot at the main.py
So, I have an idea from Flask's "BluePrint" designs.
First, we can create a proxy class to wrap event handlers.
# command/registrar.py
class CommandRegistrar:
_commands: list[Command] = []
def register(self, name: str = '', ...):
...
@classmethod
def require(cls, bot: Bot):
command_manager = bot.command
for command in cls._commands:
command_manager.add(command)
Second, We can import the proxy elsewhere and use it to register commands:
# command/help.py
from commands import CommandRegistrar
cmd = CommandRegistrar()
@cmd.register("help", aliases=["?"])
async def on_cmd(msg: Message):
...
Then, when the command package is imported, importlib will import those modules(In this example, the commands are all within the 'commands' package. ):
# command/__init__.py
import importlib
import os
from .registrar import CommandRegistrar
package = os.path.dirname(os.path.abspath(__file__))
modules = [module[:-3] for module in os.listdir(package) if
module.endswith(".py")
and os.path.isfile(os.path.join(package, module))
and module != os.path.basename(__file__)]
for module in modules:
importlib.import_module(f"{os.path.basename(package)}.{module}")
Finally, import the command package at main and use CommandRegister.require to register all commands temporarily stored in the proxy class.
# main.py
from commands import CommandRegistrar
bot = Bot(token=config.account.bot_token)
CommandRegistrar.require(bot)
The above is just an immature idea. I have found that many developers write all their code in main.py (some can even reach thousands of lines). So if these design patterns can be encapsulated in future khl.py, it will be very helpful for the organizational structure of the project.
Besides manually registering commands using the CommandManager like this:
What other methods can register commands in multi-module projects