python - 在 Signal Handler 中调用 Async 函数,Asyncio

标签 python discord.py python-asyncio

我正在使用 discord.py 制作一个 Discord 机器人,有时我用来运行它的脚本需要关闭机器人。当我在不使用信号处理程序的情况下关闭它时,有很多关于循环未关闭的错误,所以我添加了一个信号处理程序(使用下面的代码),在里面我需要调用 client.close()client.logout() ,但问题是那些是异步函数,因此需要我等待它们,但我不能等待这些函数,因为信号处理程序不能是异步函数。
这是代码:

def handler():
    print("Logging out of Discord Bot")
    client.logout()
    client.close()
    sys.exit()

@client.event
async def on_ready():
    print('We have logged in as {0.user}'.format(client))

    for signame in ('SIGINT', 'SIGTERM'):
        client.loop.add_signal_handler(getattr(signal, signame),
                                lambda: asyncio.ensure_future(handler()))
有没有办法使用信号处理程序正确注销,或者至少只是使代码内部的警告和错误静音,以便在控制台中不打印错误。

最佳答案

您的方法走在正确的轨道上 - 因为 add_signal_handler需要一个普通函数而不是异步函数,你需要调用 ensure_future (或其表亲 create_task )提交异步函数以在事件循环中运行。下一步是实际制作handler异步和 await它调用的协程:

async def handler():
    print("Logging out of Discord Bot")
    await client.logout()
    await client.close()
    asyncio.get_event_loop().stop()
注意我改了 sys.exit()显式停止事件循环,因为 asyncio 对 sys.exit() react 不佳从回调中间调用(它捕获 SystemExit 异常并提示未检索到的异常)。
由于我没有要测试的不和谐,我通过更改注销并关闭 sleep 来测试它:
import asyncio, signal

async def handler():
    print("sleeping a bit...")
    await asyncio.sleep(0.2)
    print('exiting')
    asyncio.get_event_loop().stop()

def setup():
    loop = asyncio.get_event_loop()
    for signame in ('SIGINT', 'SIGTERM'):
        loop.add_signal_handler(getattr(signal, signame),
                                lambda: asyncio.create_task(handler()))

setup()
asyncio.get_event_loop().run_forever()
如果您使用的不是 run_forever 的东西启动事件循环,例如 asyncio.run(some_function()) ,那么您将需要替换 loop.stop()使用设置主协程等待的任何事件的代码。例如,如果它等待 server.serve_forever()在服务器上,然后您将服务器对象传递给 handler并调用 server.close() , 等等。

关于python - 在 Signal Handler 中调用 Async 函数,Asyncio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66510288/

相关文章:

python - 在 Python 中合并由空格分隔的字符串

python - 如何在Python中将字符串转换为字节?

python - 如何为不同的 Perl 应用程序安装专门的环境?

Discord.py on_member_join 和 on_member_leave 不起作用

python - 更新机器人而不关闭它discord python

python - ensure_future 在异步模块中不可用

python - 在单独的线程中执行 run_coroutine_threadsafe

python - 数据框中两列或多列之间的 If 语句

python - 为什么 asyncio 中的异常迟到或根本不出现?

不和谐.ext.commands.errors.CommandNotFound : Command "balance" is not found error even though its there