python3 asyncio_python3.7 中的 async/await 以及 asyncio 问题

210792_large.png?m=1563788897

V2EX › Python

python3.7 中的 async/await 以及 asyncio 问题

waibunleung · 2019-07-16 23:36:22 +08:00 · 4196 次点击

这是一个创建于 499 天前的主题,其中的信息可能已经有所发展或是发生改变。

有一段代码:

import asyncio

async def crawl_page(url):

print('crawling {}'.format(url))

sleep_time = int(url.split('_')[-1])

await asyncio.sleep(sleep_time)

print('OK {}'.format(url))

async def main(urls):

tasks = [asyncio.create_task(crawl_page(url)) for url in urls]

for task in tasks:

await task

%time asyncio.run(main(['url_1', 'url_2', 'url_3', 'url_4']))

########## 输出 ##########

crawling url_1

crawling url_2

crawling url_3

crawling url_4

OK url_1

OK url_2

OK url_3

OK url_4

Wall time: 3.99 s

我想问在 main 函数中的 for 循环处,原意是等待所有任务结束。但是遇到第一个 await 时不会直接跳出整个 for 循环吗?还是说只是会跳过当前的一轮循环?还是说 for 循环对于 await 其实有特别的处理对待?

我也知道这个和 python 的事件循环有关系,但是在网上找了不少资料都没有很能说清楚个大概的,希望 v 友们能给我解个惑,python 的事件循环是怎么样的?

第 1 条附言 · 2019-07-17 11:07:32 +08:00

我又换了一段代码:

```python

import asyncio

import time

async def crawl_page(url):

print('crawling {}'.format(url))

sleep_time = int(url.split('_')[-1])

await asyncio.sleep(sleep_time)

print('OK {}'.format(url))

async def main(urls):

tasks = [asyncio.create_task(crawl_page(url)) for url in urls]

# for task in tasks:

# await task

await tasks[2]

await tasks[1]

await tasks[0]

await tasks[3]

start = time.time()

asyncio.run(main(['url_1', 'url_2', 'url_4', 'url_3']))

end = time.time()

print('wall time:'+ str(end - start))

########## output ###########

crawling url_1

crawling url_2

crawling url_4

crawling url_3

OK url_1

OK url_2

OK url_3

OK url_4

wall time:4.005656003952026

```

大家可以仔细看看,url 的顺序我是调换了一下的。其实和 for 循环没有太大关系

第 2 条附言 · 2019-07-17 11:22:43 +08:00

import asyncio

import time

async def crawl_page(url):

print('crawling {}'.format(url))

sleep_time = int(url.split('_')[-1])

await asyncio.sleep(sleep_time)

print('OK {}'.format(url))

async def main(urls):

tasks = [asyncio.create_task(crawl_page(url)) for url in urls]

# for task in tasks:

# await task

await tasks[2]

print('will print after tasks[2] awaited?')

await tasks[1]

await tasks[0]

print('will print after tasks[0] awaited?')

await tasks[3]

start = time.time()

asyncio.run(main(['url_1', 'url_2', 'url_4', 'url_3']))

end = time.time()

print('wall time:'+ str(end - start))

###### output #######

crawling url_1

crawling url_2

crawling url_4

crawling url_3

OK url_1

OK url_2

OK url_3

OK url_4

will print after tasks[2] awaited?

will print after tasks[0] awaited?

wall time:4.002974987030029

有没有人能解释一下这段代码的运行逻辑?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!可以使用 asyncio_mqtt 库来异步持续订阅三个 topic。以下是一个简单的示例代码: ```python import asyncio import asyncio_mqtt async def handle_message(client, topic, payload): print(f"Received message on topic '{topic}': {payload.decode()}") async def main(): client = asyncio_mqtt.Client("mqtt://localhost") # 连接 MQTT 服务器 await client.connect() # 订阅三个 topic await client.subscribe("topic1") await client.subscribe("topic2") await client.subscribe("topic3") # 循环接收消息 async with client.unfiltered_messages() as messages: async for message in messages: await handle_message(client, message.topic, message.payload) # 断开连接 await client.disconnect() if __name__ == "__main__": asyncio.run(main()) ``` 在上面的代码,我们首先创建了一个 asyncio_mqtt.Client 对象,并使用它连接到本地 MQTT 服务器。接下来,我们订阅了三个 topic,然后使用 client.unfiltered_messages() 方法获取一个消息流,循环接收消息并调用 handle_message() 函数进行处理。最后,我们在 main() 函数末尾断开了连接。 注意,上面的示例代码使用了 asyncio.run() 函数来运行主函数。这需要 Python 3.7 或更高版本。如果您使用的是早期版本的 Python,请使用以下代码替换最后一行: ```python loop = asyncio.get_event_loop() loop.run_until_complete(main()) ``` 希望这可以帮助您开始使用 asyncio_mqtt 订阅多个 topic。如果您有任何问题,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值