协程语法
"""
该函数执行时得到的是一个协程对象
"""
import asyncio
async def func():
print("我是函数")
def gen():
yield 1
if __name__ == '__main__': # 程序入口
# 协程对象想要执行,必须借助于 event_loop
# f = func()
# print(f)
f = func() # 协程对象想要执行,必须借助于 event_loop
# # 拿到事情循环
# event_loop = asyncio.get_event_loop()
# # event_loop执行协程对象,直到该对象的内容执行完毕为止
# event_loop.run_until_complete(f)
asyncio.run(f)
# 如果你的电脑报错:Event Loop has closed!!!
def run(main, *, debug=None)函数语法
# def run(main, *, debug=None):
# """Execute the coroutine and return the result.
#
# This function runs the passed coroutine, taking care of
# managing the asyncio event loop and finalizing asynchronous
# generators.
#
# This function cannot be called when another asyncio event loop is
# running in the same thread.
#
# If debug is True, the event loop will be run in debug mode.
#
# This function always creates a new event loop and closes it at the end.
# It should be used as a main entry point for asyncio programs, and should
# ideally only be called once.
#
# Example:
#
# async def main():
# await asyncio.sleep(1)
# print('hello')
#
# asyncio.run(main())
# """
# if events._get_running_loop() is not None:
# raise RuntimeError(
# "asyncio.run() cannot be called from a running event loop")
#
# if not coroutines.iscoroutine(main):
# raise ValueError("a coroutine was expected, got {!r}".format(main))
#
# loop = events.new_event_loop()
# try:
# events.set_event_loop(loop)
# if debug is not None:
# loop.set_debug(debug)
# return loop.run_until_complete(main)
# finally:
# try:
# _cancel_all_tasks(loop)
# loop.run_until_complete(loop.shutdown_asyncgens())
# finally:
# events.set_event_loop(None)
# loop.close() # 注意!!! 一般会出现报错的是windows系统下,如果你的电脑报错:Event Loop has closed!!!
协程用途
import asyncio
import time
## async def func1():
# print("我是func1")
# await asyncio.sleep(1)
# print("func1结束")
#
# async def func2():
# print("我是func2")
# await asyncio.sleep(2)
# print("func2结束")
#
#
# async def func3():
# print("我是func3")
# await asyncio.sleep(3)
# print("func3结束")
#
# if __name__ == '__main__':
# start = time.time()
# f1 =func1()
# f2 =func2()
# f3 = func3()
#
# # 把三个任务放在一起
#
# tasks = [
# f1,
# f2,
# f3,
# ]
#
# asyncio.run(asyncio.wait(tasks))
# print(time.time() - start)
async def download(url, t):
print("我要下载了")
await asyncio.sleep(t)
print("我下载完了")
async def main():
# 假设已经有了一堆下载链接
urls = [
'http://www.baidu.com',
'http://louyonghao.com',
'http://xinfadi.com'
]
# 需要封装任务列表
tasks = []
for url in urls:
# 创建任务
task = asyncio.create_task(download(url, 3))
# 把任务扔到列表,为了统一处理
tasks.append(task)
# tasks.append(download(url, 3))
# 统一等到协程任务执行完毕
await asyncio.wait(tasks) # py3.8以上的,这里可能会出现警告。
if __name__ == '__main__':
asyncio.run(main())
# event_loop = asyncio.get_event_loop()
# event_loop = asyncio.get_event_loop(main())
"""
未来爬虫:
1.扫url,拿到一堆url
2.循环url,创建任务
3.统一await
"""
协程返回值
import asyncio
async def func1():
print("我是func1")
await asyncio.sleep(1)
print("func1结束")
return "func1的返回值"
async def func2():
print("我是func2")
await asyncio.sleep(2)
print("func2结束")
return "func2的返回值"
async def func3():
print("我是func3")
print(1/0) # 异常
await asyncio.sleep(3)
print("func3结束")
return "func3的返回值"
async def main():
f1 = func1()
f2 = func2()
f3 = func3()
tasks = [
asyncio.create_task(f2), # 2 1 3 3 2 1
asyncio.create_task(f1),
asyncio.create_task(f3),
]
# # 结束 ,运行,set集合:无序
# # asyncio.wait() 返回的结果,没有顺序
# done, pending = await asyncio.wait(tasks)
#
# for t in done:
# print(t.result())
# def gather(*coros_or_futures, loop=None, return_exceptions=False):
# gather 和 wait的区别:gather返回值是有顺序(按照你添加任务的顺序返回的)。 返回值 异常
# return_exceptions=True,如果有错误信息,返回错误信息,其他任务正常执行
# return_exceptions = False 如果有错误信息,所有任务直接停止
result = await asyncio.gather(*tasks,return_exceptions=True) # ,return_exceptions=False
print(result) # 2 1 3
if __name__ == '__main__':
asyncio.run(main())