Py-cord运行时错误:在主线程中没有当前的事件循环
我回到了几个月前用py-cord模块创建的那个机器人上,当前是在一台新设备上重新安装了py-cord。最初开发它时机器人加载得很正常,但现在我尝试运行它时,py-cord包在asyncio中抛出一个RuntimeError循环,如下所示:
C:\Users\jrowt\Documents\Dungeon Coursers\Rollerbot>py main.py
Traceback (most recent call last):
File "C:\Users\jrowt\Documents\Dungeon Coursers\Rollerbot\main.py", line 6, in <module>
bot = discord.Bot()
File "C:\Users\jrowt\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\discord\bot.py", line 1154, in __init__
super().__init__(*args, **options)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "C:\Users\jrowt\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\discord\bot.py", line 85, in __init__
super().__init__(*args, **kwargs)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "C:\Users\jrowt\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\discord\cog.py", line 621, in __init__
super().__init__(*args, **kwargs)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "C:\Users\jrowt\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\discord\client.py", line 220, in __init__
asyncio.get_event_loop() if loop is None else loop
~~~~~~~~~~~~~~~~~~~~~~^^
File "C:\Users\jrowt\AppData\Local\Python\pythoncore-3.14-64\Lib\asyncio\events.py", line 715, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
% threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'MainThread'.
我试过不少办法,但仍没法搞清楚到底出了什么问题。我在想是否存在某种与代码外部相关的问题,导致事件循环在应当创建时没有被创建,可能与Discord机器人管理有关,但我还没找到相关信息。
即使把main.py文件简化到最基本的机器人设置代码,我仍然会看到这个错误,所以我知道这不是我写的代码的问题。显然,除非真的必要,我不想去拆开py-cord的代码。
这里有没有人能告诉我,是否有外部原因导致Discord客户端在应当创建事件循环时没有创建,比如是否对Discord机器人工作方式做了变化?我已经附上了py-cord的 client.py文件中loop类的描述:
loop: Optional[:class:`asyncio.AbstractEventLoop`]
The :class:`asyncio.AbstractEventLoop` to use for asynchronous operations.
Defaults to ``None``, in which case the default event loop is used via
:func:`asyncio.get_event_loop()`.
这是client.py中 get_event_loop() 被执行的地方:
self.loop: asyncio.AbstractEventLoop = (
asyncio.get_event_loop() if loop is None else loop
)
解决方案
在Python 3.14中,asyncio.get_event_loop() 不再在没有设置时为你创建一个循环;它现在会抛出 RuntimeError。py-cord仍然在 Client.__init__ 这样做:
asyncio.get_event_loop() if loop is None else loop
因此在模块导入时的 bot = discord.Bot() 现在在3.14上会抛出错误。
这意味着在当前的py-cord代码路径下,最小重现应在3.14上出现。PyPI只说py-cord需要Python 3.10+,但这并不保证这种构造模式在3.14上保持不变。
请使用以下其中一种修复方法:
import asyncio
import discord
TOKEN = "..."
async def main():
bot = discord.Bot()
await bot.start(TOKEN)
asyncio.run(main())
这之所以有效,是因为 discord.Bot() 现在是在正在运行的事件循环中创建的,所以 get_event_loop() 有一个可返回的对象。
如果你想要最不容易让人吃惊的修复,建议在py-cord更新该代码路径之前,使用Python 3.13或 3.12来完成这个项目。Python 3.12只是对这种行为发出警告;3.14将其改为错误。
所以简短的回答是:不,这不是Discord端在机器人管理方面的变动。这是Python 3.14的 asyncio行为变更,与py-cord的构造函数发生了交互。