Skip to main content
 首页 » 编程设计

python之@client.event 到底是什么不和谐.py

2025年05月04日15kevingrace

几天前,我对编写 discord 机器人有点感兴趣。在这些程序的语法中,我注意到很多我找不到答案的难以理解的问题。 这就是我请求您帮助理解它们的原因。

所有问题都基于这段代码:

import discord 
import asyncio 
from discord.ext import commands 
 
botToken = '***' 
 
client = commands.Bot(command_prefix = '.') 
 
@client.event 
async def on_ready(): 
    print('Bot is ready!') 
 
@client.event 
async def on_message(message): 
    author = message.author 
    if message.content =='Hello': 
        await client.send_message(message.channel, 'Welcome again {}!'.format(author)) 
 
 
client.run(botToken) 

什么是@client.event?我发现这是一个事件处理程序,但它是如何工作的?为什么需要运行程序?它是否以某种方式连接到 asyncio?

请您参考如下方法:

当 Client 从 Discord 接收到一个事件时,它会计算出该事件是什么并生成或定位该事件发送的对象,例如 discord.Message 用于任何 MESSAGE_RECEIVE 事件,或 discord.Reaction 用于 REACTION_ADD 等。
然后客户端将对象发送到处理这些事件的方法中,但您首先需要告诉客户端这些方法是什么。这就是事件装饰器发挥作用的地方。


装饰器本质上是将其他函数作为参数的函数。您将看到的最常见的是 @property。这表示您定义的函数应该传递给 property() 函数

@property 
def name(self): 
    return self._name 

与

相同
def name(self): 
    return self._name 
 
name = property(name) 

这可能会让您有些困惑,但这就是 discord.py 处理其事件的方式。


当您在 on_message 上使用 @client.event 装饰器时,您实际上在说 on_message = client.event(on_message)

on_event 的 discord.py 内部代码是 this

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

这意味着它将函数作为其参数,并在客户端本身上设置一个新属性。对于我们的 on_message 示例,我们将我们的 on_message 函数传递给 client.event() 并使客户端定义一个新的 client。 on_message 方法,与我们的 on_message 方法相同。

注意:func.__name__ 返回该函数的名称。 on_message.__name__ 将返回 "on_message"。
setattr(obj, name, value) 设置对象的属性,所以 setattr(self, "foo", 100) 表示 self.foo 将是 100。

既然客户端知道了我们的 on_message,当它收到一个表明消息已发送的事件时,它会创建 discord.Message 对象并将其传递给 client.on_message,我们已经建立的,和我们自己的on_message

是一样的

如果您愿意,您甚至可以跳过装饰器并在您的函数之后执行此操作,但它不如装饰器优雅:

on_message = client.event(on_message)