What it really is @client.event? discord.py What it really is @client.event? discord.py python-3.x python-3.x

What it really is @client.event? discord.py


When a Client receives an event from Discord, It works out what that event is and generates, or locates, the objects that were sent by the event, such as a discord.Message for any MESSAGE_RECEIVE events, or a discord.Reaction for REACTION_ADD etc.
The client then sends the objects into the method that handles those events, but you first need to tell the client what those methods are. This is where the event decorators come in.


Decorators are, in essence, functions that take other functions as arguments. The most common one you'll see is @property. This says that the function you define should be passed into the property() function

@propertydef name(self):    return self._name

is the same as

def name(self):    return self._namename = property(name)

This may be a bit confusing to wrap your head around, but this is how discord.py handles its events.


When you use the @client.event decorator on your on_message, what you are actually doing is saying on_message = client.event(on_message)

The internal code of discord.py for on_event is this

def event(self, coro):    # Validation we don't need to worry about    setattr(self, coro.__name__, coro)    return coro

Which means that it takes the function as its parameter, and sets a new attribute on the client itself. For our on_message example, we pass our on_message function into client.event() and it makes the client define a new client.on_message method that is the same method as our on_message.

Note: func.__name__ returns the name of that function. on_message.__name__ will return "on_message".
setattr(obj, name, value) sets an attribute on an object, so setattr(self, "foo", 100) means that self.foo will be 100.

Now that the client knows our on_message, when it receives an event saying that a message was sent, it creates the discord.Message object and passes that into client.on_message, which as we already established, is the same as our own on_message

If you wanted, you could even just skip the decorator and do this after your function, but it is less elegant than a decorator is:

on_message = client.event(on_message)