问题
As stated in the title, how? I'm really struggling with understanding the documentation as there are no examples of anything. How do I define something like a VoiceState, Member, VoiceChannel, etc...
Running on tutorials is fine until you have to start consulting the documentation for something specific, at which point it becomes really frustrating when you have no idea how to define objects or use certain commands...
回答1:
A lot of this will come from experience, so don't be discouraged if it takes a while to get the hang of! I know that the docs can be a bit daunting, but I'll try to help as best I can by giving a couple of examples.
When making a discord bot, usually you're going to be getting information based off of arguments and ctx (context).
First I'll start off with some general examples, and then I'll move onto how to use these when working with d.py.
Parameters and args
When you create functions in python, you can define parameter types:
def my_func(a: int):
return a + 5
What this does is assume that the args passed into my_func
will be integers, and therefore behave as int
s too:
my_func(1)
Will return, as you might expect, 6
.
However, when you try to pass in something like so:
my_func("1")
You'll get a TypeError
which complains about concatenating str and int. Additionally, you can see the differences in an object when you list its attributes like so: dir(obj)
When applying this same concept to a command:
@bot.command()
async def cmd(ctx, member: discord.Member):
await ctx.send(f"Hello, {member.mention}!")
But when using commands, what it does is it's able to get a member based off of an attribute you enter, such as the member's ID or name. The member that it finds, then has all of the discord.Member object's attributes.
This means you'll be able to access things such as the member's roles, which return a list containing each role as a discord.Role object, which from there, you can get the role's attributes, and so on and so forth.
SIDE-NOTE:
Another way of getting objects in d.py is by using discord.utils. It takes in an iterable, e.g. a list, as the first argument, and then after that it takes keyword arguments, such as name
, id
, colour
, or any attributes of an abc to return an object.
Example:
@bot.command()
async def getrole(ctx):
role = discord.utils.get(ctx.author.roles, name="Very Special Role!", mentionable=True)
await ctx.send(f"Look at you with your {role.mention} How classy!")
And that will iterate through each of the message sender's roles, looking for the name (case sensitive) Very Special Role!
which is mentionable, and it will send the message using one of the role's attributes; mention.
Context
With commands, the first argument you're going to be passing in is Context, which by convention is denoted as ctx
.
As shown in the link, it has a range of attributes, which revolve mostly around the command's origin, author, and all other details about it etc.
@bot.command()
async def hello(ctx):
await ctx.send(f"Hello, {ctx.author.name}!")
In the command there, I'm using the coroutine from context called send(), which is used for sending messages.
And in the context of the command, it'll be sending it to the same channel, which is how that works.
Also, an example of some commonly used superfluous code:
ctx.message.channel.send("some message")
ctx.message.author.send("some dm")
can be respectively turned into:
ctx.send("some message")
ctx.author.send("some dm")
But how do you know where you can send()
a message to? Well that brings us onto the next part:
Abstract Base Classes
These are, what I'm assuming you were talking about when you were on about defining objects. They are the base templates for objects to inherit from - for example, TextChannel has inherited all of Messageable
's attributes (except connectable
, which is only inherited by discord.VoiceChannel.channel.
I'll use abc.Messageable as an example. In the link, it gives us examples of some Messageable objects, i.e. where you can send messages to, and these are objects such as TextChannels, Members etc.
Occasionally I see someone miss out an await
or not know when to add them, or add them too often. You'll know when to add one, as the docs will state whether the function is a couroutine or not, for example:
That's how you know what you can do with each object - think of these as templates for the objects you get within discord, not something that you define!
If you need any further clarification or if you noticed any mistakes with my answer, please let me know.
References:
- commands.Command() - decorator for commands
- commands.Context
- Coroutines
- discord.Member
- Member.roles
- discord.Role
- Context.send()
- discord.TextChannel
- discord.utils
- discord.abc
来源:https://stackoverflow.com/questions/61869972/how-to-define-objects-in-discord-py-rewrite