【发布时间】:2021-03-10 04:54:48
【问题描述】:
我正在用 Python 创建一个命令系统。我有一个模块vkcommands,它有一个处理来自聊天的命令的类(这是一个聊天机器人),在其中,我还有一个类VKCommand,其属性如name、usage、min_rank、等等。然后我有模块 vkcmds 和实现这些命令的子模块:
...
vkcommands.py
vkcmds
|- __init__.py # empty
|- add_group.py
|- another_cmd.py
|- ...
命令的实现(例如add_group)如下所示:
import ranks
import vkcommands
from vkcommands import VKCommand
class AddGroup(VKCommand):
def __init__(self, kristy):
VKCommand.__init__(self, kristy,
label='create',
# ... (other attributes)
min_rank=ranks.Rank.USER)
def execute(self, chat, peer, sender, args=None, attachments=None):
# implementation (called from vkcommands.py)
当用户在聊天中发送消息时,命令管理器会对其进行分析并查看已注册的commands 列表,以确定这是普通消息还是机器人命令。目前我像这样手动注册commands列表中的所有命令:
class VKCommandsManager:
def __init__(self, kristy):
from vkcmds import (
add_group,
next_class
)
self.kristy = kristy
self.commands = (
add_group.AddGroup(kristy),
next_class.NextClass(kristy)
)
现在我希望使用反射自动注册所有命令。在 Java 中,我会遍历命令包中的所有类,反射性地为每个类 getConstructor,调用它来检索VKCommand 对象,并将其添加到命令列表中。
如何在 Python 中做到这一点? 同样,我需要:
- 遍历模块(文件夹)
vkcmds/中的所有子模块; - 对于每个子模块,检查内部是否有一些类
X扩展了VKCommand; - 如果 (2) 是
true,则使用一个参数调用该类的构造函数(保证所有命令的构造函数只有一个已知类型的参数(我的机器人主类)); - 将 (3) 中构造的对象 (
? extends VKCommand) 添加到commands列表中,以便稍后进行迭代。
【问题讨论】:
-
我认为您可以在
__init__.py中创建所有命令的列表,然后遍历所有命令并构建它们。 -
整个问题是我如何构建它们。我已经能够弄清楚如何列出模块的所有子模块,但是如何检查它们是否有特定的类,以及如何实际初始化该类?
-
像调用函数一样实例化一个类:
obj = AddGroup(arg1, arg2, ...) -
我想反思一下。无需自己为每个命令键入类或构造函数的名称。这样我就可以创建一个新的子模块,比如
vkcmds/new_cmd.py,在其中创建一个扩展VKCommand的类,执行命令,然后什么都不做——该命令应该自动注册,而无需我编写“import new_cmd / // commands.append(NewCmd(...))"
标签: python python-3.x reflection chatbot python-class