python discord discord.py

python - ¿Por qué no funcionan múltiples eventos on_message?



discord discord.py (2)

¿Por qué no puedo tener múltiples eventos 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")

Por ejemplo, si escribí algo en discordancia, siempre es el último on_message que se dispara. ¿Cómo puedo hacer que los tres funcionen?


No es posible con el Client nativo.

Solo puede tener un on_message , si tiene varios, solo se llamará al último para el evento on_message . Solo necesitarás combinar tus tres 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")

Como cualquier variable / función de Python (a menos que el decorador almacene su función, @client.event hace manteniendo solo la devolución de llamada más reciente), si hay varios nombres iguales, se conservará el más reciente y todos los demás se sobrescribirán.

Este es un ejemplo simple que escribí para brindarle una amplia comprensión de cómo funcionan los eventos en discord.py (nota: el código real no es exactamente así, ya que se reescribió y redujo significativamente).

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"

Como puede ver client.event solo mantenga una instancia de on_message .

Puedes con instancias de Bot

Alternativamente, si está utilizando la extensión ext.commands de discord.py, existe una forma nativa de tener múltiples on_message llamada en on_message . Puedes hacerlo definiéndolos como un listener . Puede tener como máximo un evento on_message y una cantidad infinita de oyentes 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")

Cuando se recibe un mensaje, todos los on_message #1-3 se imprimirán.


En Python, las funciones son solo objetos.

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

define un objeto llamado foo , puedes ver esto usando un shell de Python.

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

Si define un nuevo método después de, o redefine la variable foo , perderá el acceso a la función inicial.

>>> foo = "hi" >>> foo hi >>> foo() Traceback ...: file "<stdin>" ... TypeError: ''str'' object is not callable

Cómo funciona el decorador de @client.event es que le dice a su cliente que los mensajes nuevos deben canalizarse a los mensajes, y bueno, si el método se redefine, significa que el método anterior se ha perdido.

>>> @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