Utility Functions
In this lesson, you’ll clean up your code by using more functions from discord.py
, namely the utility functions. The first utility, discord.utils.find()
, can improve the simplicity and readability of this code by replacing the for
loop with an intuitive, abstracted function. find()
takes a function, called a predicate, which identifies some characteristic of the element in the iterable that you’re looking for.
The other utility you’ll practice with is get()
, which takes the iterable and some keyword arguments. The keyword arguments represent attributes of the elements in the iterable that must all be satisfied for get()
to return the element.
00:00 This is part seven, where you will begin exploring utility functions. Let’s start by taking another look at the example from the last video, which printed the name and identifier of the bot’s guild.
00:12
You could potentially clean up this code by using some of the utility functions from discord.py
. One of these utility functions is called discord.utils.find()
, which can improve the simplicity and readability of this code by replacing the for
loop with an intuitive abstracted function.
00:29 Let’s implement that now.
00:33
What happens here is find()
takes a function, called a predicate, which identifies some characteristic of the element in the iterable that you’re looking for. Here, you will use a particular type of anonymous function, called a lambda, as the predicate. In this case, you’re trying to find the guild with the same name as the one that is stored in the DISCORD_GUILD
environment variable. Once find()
locates an element within the iterable that satisfies the predicate, it will return the element.
01:05
This is essentially equivalent to the break
statement in the previous example, but quite a bit cleaner. If you’re unsure what a lambda function is, there will be a link below the video to a tutorial on the Real Python site about it. Let’s confirm that this change works.
01:26
And there we go, we get the same output as we did previously. Now, discord.py
has actually abstracted this concept that we just implemented one step further with the get()
utility. So, we can change this find()
function to
01:42
a get()
, and then we can clean this up
01:48
and make it a little bit nicer, a little bit easier to read, just like that. Now, what’s happening here? get()
takes the iterable and some keyword arguments.
02:01
The keyword arguments represent attributes of the elements in the iterable that must all be satisfied for get()
to return the element. In this particular example, you have identified name=guild
, just here, as the attribute that must be satisfied. Now, if you take a brief look under the hood here and explore a technical detail, the get()
function, here, actually uses the attrs
keyword arguments to build a predicate, which it then uses to call find()
. In case you missed it, I do mean attrs
, like that. Don’t leave that there, because it will break your code.
02:41
Now that you have explored the basics of interacting with APIs, get prepared for diving a little deeper into the function that you have been using to access them: on_ready()
.
02:52
Let’s now take a look at how to respond to events. You have already learned that on_ready()
is an event. You may have even noticed that it is identified as such in the code by the client.event
decorator.
03:06 But what exactly is an event? An event is something that happens on Discord that you can use to trigger a reaction in your code. Your code will listen for and then respond to events.
03:18
Using the example that you’ve already seen, the on_ready()
event handler handles the event that the Client
has made a connection to Discord and prepared its response data.
03:29
So, when Discord fires an event, discord.py
will route the event data to the corresponding event handler on your connected client.
03:39
There are two ways in discord.py
to implement your event, handler: the client.event
decorator, and creating a subclass of Client
and
03:49
overriding its handler methods. You already saw the implementation using the decorator. Next up, take a look at how to subclass Client
.
03:59
What you have done here is, just like before, created a client
variable and called the run()
method with your Discord token. However, the actual Client
is different. Instead of using the normal base class, client
is an instance of CustomClient
, just here, which has an overridden on_ready()
function.
04:21
There is no real difference between the two implementation styles. However, moving forward in this tutorial course, the decorator version is the one that will be primarily used, as it looks quite similar to how you implement Bot
commands, which is something you will explore how to do in due time.
04:38
A quick technical detail that should be mentioned at this point is that regardless of how you implement your event handler, one thing must be consistent: all event handlers in discord.py
must be coroutines.
04:52 In case you are unfamiliar with the term, a coroutine is a specialized version of a Python generator function. There will be a link to a tutorial on it below the video. Before moving any further, we should double check that this version works, so if we run it, it’s connected to Discord. There you go.
05:10 We’ve got the bot name and it’s telling us it’s successfully connected. Very good! That’s what we wanted to see. This is the point where it is now time for you to start walking through examples of different event handlers that you can create.
Bartosz Zaczyński RP Team on June 21, 2021
@prashantsekuri Coroutines are mentioned in the AsyncIO in Python walkthrough tutorial.
Become a Member to join the conversation.
prashantsekuri on June 19, 2021
Hi There is no link to the tutorial on coroutines in the description. Please let me know if i am supposed to look for it elsewhere. Thanks