因此,我尝试制作自己的装饰器,与discord.py模块中提供给我们的内置冷却器装饰器非常相似,不同之处在于,我试图使其在常规函数(例如非“ @client”)上运行。命令async def myCommand()“函数)。
我有一个函数,当用户说“你好”时会向用户说“你好”,但是我不希望他们一遍又一遍地向用户发送垃圾邮件,并导致机器人也向其发送垃圾邮件。这是我目前所拥有的:
@client.event
async def on_message(message):
if message.content == "hello":
try:
await sayHello(message)
except Exception as err:
print(err)
helloCooldown = commands.CooldownMapping.from_cooldown(1.0, 20.0, BucketType.user)
async def sayHello(message):
bucket = helloCooldown.get_bucket(message)
retry_after = bucket.update_rate_limit()
if retry_after:
return # exits function if on cooldown / is rate limited
author = message.author
channel = message.channel
await channel.send(f"Hello, {author.name}")
我创建的装饰器接受放置在非命令函数上的速率,每和类型(类似于内置的):
def myCooldown(rate, per, type):
def outer(func):
def inner(*args):
cd = commands.CooldownMapping.from_cooldown(rate, per, type)
bucket = cd.get_bucket(args[0]) # get 'message' argument from the original function
retry_after = bucket.update_rate_limit()
if retry_after:
return # exit out if its on cooldown/ rate limited
else:
return func # executes function if not on cooldown
return inner
return outer
@myCooldown(1.0, 20.0, BucketType.user)
async def sayHello(message):
# say hello
预期的行为是,如果被调用,它将保持冷却20秒,然后再次说“你好”。但是,我收到错误消息“ Object function cant be used in 'await' expression
”。我该如何修复我的装饰器使其按我打算的方式工作?
答案 0 :(得分:0)
当您尝试await sayHello(message)
时,首先执行sayHello(message)
(实际上是inner(message)
),并返回func
。
您的程序尝试运行await func
,这实际上没有意义,因此会引发错误。
您需要更改inner
,以便它返回一个等待对象。这意味着它不能返回None
,因此您应该引发一个错误。
from discord import DiscordException
class FunctionOnCooldown(DiscordException):
pass
def myCooldown(rate, per, type):
def outer(func):
cd = commands.CooldownMapping.from_cooldown(rate, per, type)
def inner(message, *args, **kwargs):
bucket = cd.get_bucket(message)
retry_after = bucket.update_rate_limit()
if retry_after:
raise FunctionOnCooldown
else:
return func(*args, **kwargs) # executes function if not on cooldown
return inner
return outer