# 前言
之前尝试用 python 的 telethon 开发时,由于不太了解 python 遇到不少坑
幸运的是通过 Google 从前人哪里找到了解决办法
其中一个问题让我影响深刻,为了弄清楚为什么,我又回头了解 asyncio eventLoop
这个过程让我更加了解 python
# RuntimeError: There is no current event loop in thread 'Thread-1'.
意思是线程中没有当前事件循环
字我都认识,但是组合起来后,没看懂什么意思
不过幸好找到了解决办法,加上下面的两行代码就行,顺利解决了
不过虽然解决了,但我还是不知道为什么,于是便抽空仔细阅读了关于 asyncio 的内容
new_loop = asyncio.new_event_loop() | |
asyncio.set_event_loop(new_loop) |
# 参考地址
- https://blog.csdn.net/u013421629/article/details/100163014 (解决办法)
- https://stackoverflow.com/questions/51311383/python-flask-with-telethon (里面说和 asyncio 有关)
- https://blog.csdn.net/qq_34341423/article/details/102874263 (eventLoop 的使用)
# 探究过程
之前有看到关于 EventLoop 的介绍,但是没心思看下去
自己遇到的了问题,才有探究的动力
于是我试着通过代码了解它
# 首先写一段代码 简单了解 asyncio eventLoop
文件名 test.py
import asyncio | |
async def coroutine_example(): | |
await asyncio.sleep(3) | |
print('task') | |
if __name__ == '__main__': | |
coro = coroutine_example() | |
loop = asyncio.get_event_loop() | |
loop.run_until_complete(coro) | |
loop.close() |
async await 很熟悉的异步语法糖
测试过程中发现 必须加入 run_until_complete 才能执行,直接执行就会提示错误
# 在线程 (thread) 中执行 EventLoop
在阅读文章时,看到这么一句话
get_event_loop () 只会在主线程帮您创建新的 event loop,而在其他线程中调用 get_event_loop () 则会报错
结合之前遇到的问题,所以是因为在线程中执行 EventLoop,引发了错误
写了个简单的关于线程代码,并调用 EventLoop
通过注释,新建 eventLoop 部分代码,验证了非主线程没有 EventLoop
python3.7 以后 asyncio.run (coroutine_example ()) 就能代替上面 4 行代码的效果
文件名 thread.py
import asyncio | |
import time | |
from threading import Thread | |
from test import coroutine_example | |
def func(name): | |
print(f"{name}开始") | |
time.sleep(0.5) | |
print(f"{name}结束") | |
#新建 eventLoop | |
new_loop = asyncio.new_event_loop() | |
asyncio.set_event_loop(new_loop) | |
#执行异步方法 | |
loop = asyncio.get_event_loop() | |
loop.run_until_complete(coroutine_example()) | |
# asyncio.run(coroutine_example()) | |
if __name__ == '__main__': | |
t1 = Thread(target=func, args=("线程1",)) | |
t2 = Thread(target=func, args=("线程2",)) | |
t1.start() | |
t2.start() | |
print("主线程结束") |
# 个人理解总结
python async 异步 需要通过 loop.run_until_complete 启动
默认主线程有 eventLoop,可以直接 get_event_loop
其他线程执行 async 异步,需要新创建 eventLoop, new_event_loop 后才能获取 get_event_loop,不然会提示错误
python3.7 以后, asyncio.run 以更简洁代码的启动 async