超过最大递归深度 discord.py 机器人循环

Maximum recursion depth exceeded discord.py bot loop

我的机器人有提醒功能。它每 10 秒检查一次提醒是否现在,如果是,它会发送一条消息。

async def reminder():
    global reminderDone
    if datetime.now().replace(second = 0, microsecond=0) == datetime(2021, 1, 29, 19) and not reminderDone:
        reminderDone = True
        cnl = bot.get_channel([channel id goes here])
        await cnl.send("@everyone Reminder time")
    await asyncio.sleep(10)
    await reminder()

首先在on_ready()中用await reminder()调用。大约 3 小时后,我收到此错误:

File "/app/.heroku/python/lib/python3.6/site-packages/discord/client.py", line 333, in _run_event
  await coro(*args, **kwargs)
File "bot.py", line 21, in on_ready
  await reminder()
File "bot.py", line 36, in reminder
  await reminder()
File "bot.py", line 36, in reminder
  await reminder()
File "bot.py", line 36, in reminder
  await reminder()
[Previous line repeated 976 more times]
File "bot.py", line 35, in reminder
  await asyncio.sleep(10)
File "/app/.heroku/python/lib/python3.6/asyncio/tasks.py", line 480, in sleep
  future, result)
File "/app/.heroku/python/lib/python3.6/asyncio/base_events.py", line 564, in call_later
  timer = self.call_at(self.time() + delay, callback, *args)
File "/app/.heroku/python/lib/python3.6/asyncio/base_events.py", line 578, in call_at
  timer = events.TimerHandle(when, callback, args, self)
File "/app/.heroku/python/lib/python3.6/asyncio/events.py", line 167, in __init__
  super().__init__(callback, args, loop)
File "/app/.heroku/python/lib/python3.6/asyncio/events.py", line 110, in __init__
  if self._loop.get_debug():
RecursionError: maximum recursion depth exceeded

我假设这是因为函数调用自身引起的,但因为它正在使用 await 它等待函数停止执行,它永远不会因为它不断调用自己。我不能只删除 await,因为我需要它来发送消息 (await cnl.send()),这是一个协程。我如何永久使用循环 运行 检查提醒而不会出现递归错误?

编辑 2: 不要使用我的答案,使用 quamrana 一个,它很简单并修复你的代码。

很简单,你从自身调用 reminder 函数,(递归)但没有停止,然后,为了防止解释器重复无限次,Python 抛出这个错误当你函数调用太多了。

解决这个问题

只需在您的代码中添加一个 if,例如:

if foo==True:
   reminder()

编辑: 不要使用 stop()!它只是停止循环

如果您要无限循环,那么您需要一个 while 循环:

async def reminder():
    while True:
        global reminderDone
        if datetime.now().replace(second = 0, microsecond=0) == datetime(2021, 1, 29, 19) and not reminderDone:
            reminderDone = True
            cnl = bot.get_channel([channel id goes here])
            await cnl.send("@everyone Reminder time")
        await asyncio.sleep(10)

您可以简单地创建一个循环,而不是一次又一次地调用同一个函数...

from discord.ext import tasks

@tasks.loop(seconds=10)
async def reminder():
    global reminderDone
    if datetime.now().replace(second = 0, microsecond=0) == datetime(2021, 1, 29, 19) and not reminderDone:
        reminderDone = True
        cnl = bot.get_channel([channel id goes here])
        await cnl.send("@everyone Reminder time")


reminder.start()

参考: