为什么没有多个on_message事件有效?

时间:2018-05-03 23:33:25

标签: python discord discord.py

为什么我不能有多个on_message事件?

import discord

client = discord.Client()

@client.event
async def on_ready():
    print('in on_ready')

@client.event
async def on_message(message):
    print("in on_message #1")

@client.event
async def on_message(message):
    print("in on_message #2")

@client.event
async def on_message(message):
    print("in on_message #3")

client.run("TOKEN")

例如,如果我输入了不和谐的内容,那么它始终只是被触发的最后一个on_message。我怎样才能让这三个人都工作?

2 个答案:

答案 0 :(得分:3)

使用原生Client

是不可能的

您只能拥有一个 on_message,如果您有多个,则只会为on_message事件调用最后一个。您只需要合并三个on_message

import discord

client = discord.Client()

@client.event
async def on_message(message):
    print("in on_message #1")
    print("in on_message #2")
    print("in on_message #3")

client.run("TOKEN")

与任何Python变量/函数一样(除非装饰器存储您的函数,@client.event通过仅保留最近的回调来实现),如果多个名称相同,最近将保留,以及所有其他名称将被覆盖。

这是一个简单的例子,我写的是为了让你广泛了解discord.py中的事件是如何工作的(注意:实际代码并不完全像这样,因为它被重写并显着减少)。

class Client:
    def event(self, func):               
        if func.__name__ == "on_message":
            self.on_message_handle = func
            return func

    def receive_message(self, msg):
        func = getattr(self, "on_message_handle", None)
        if func is not None:
            func(msg)
        else:
            self.process_commands(msg)

client = Client()

@client.event
def on_message(msg):
    print("in on_message #1")

@client.event
def on_message(msg):
    print("in on_message #2")

client.receive_message("hello")
# "in on_message #2"

正如您所看到的,client.event只保留on_message的一个实例。

您可以使用Bot个实例

或者,如果您使用的是discord.py的ext.commands扩展名,则有一种原生方式可以有多个on_message回调。您可以将它们定义为listener来实现。您最多只能有一个on_message个事件,以及无限量的on_message个侦听器。

from discord.ext import commands

bot = commands.Bot('.')

@bot.event
async def on_message(msg):
    print("in on_message #1")
    await bot.process_commands(msg)  # so `Command` instances will still get called


@bot.listen()
async def on_message(msg):
    print("in on_message #2")


@bot.listen()
async def on_message(msg):
    print("in on_message #3")

bot.run("TOKEN")

收到邮件后,所有on_message #1-3都将被打印。

答案 1 :(得分:0)

在python中,函数只是对象。

>>> def foo():
...     print ("hi")

定义了一个名为foo的对象,您可以使用Python shell看到它。

>>> foo
<function foo at 0x...>
>>> foo()
hi

如果在变量foo之后定义新方法或重新定义变量>>> foo = "hi" >>> foo hi >>> foo() Traceback ...: file "<stdin>" ... TypeError: 'str' object is not callable ,则无法访问初始函数。

@client.event

>>> @bot.event ... async def on_message(m): ... print(1) ... >>> bot.on_message(None) # @bot.event makes the bot define it's own method 1 >>> @bot.event ... async def on_message(m): ... print(2) ... >>> bot.on_message(None) # bot's own method was redefined. 2 装饰器是如何工作的,它告诉你的客户端应该将新消息传递到消息中,如果方法被重新定义,则意味着旧方法丢失。

{{1}}