【Python进阶】asnycio的一些小常识

以aiohttp为例, 以下封装了一个aiohttp的网页请求。

from aiohttp import ClientSession
from asyncio import get_event_loop
from asyncio import ensure_future
from asyncio import gather
from functools import partial


async def aio_request(kwargs):
    async with ClientSession() as session:
        response = await session.request(**kwargs)
    try:
        context = await response.text(encoding='utf-8')
    except UnicodeDecodeError:
        context = await response.text(encoding='gbk')
    return context

def callback_None(future):
	print(future.result())


def callback(a, future):
    print(future.result())
    print(a)

那么问题来了,怎么拿到异步函数的返回值呢,以下抛出3种方法。

URL = 'http://toefl.koolearn.com/20160819/810320.html'
METHOD = 'get'
HEADERS = {
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/77.0.3865.90 Safari/537.36',
}
REQUEST_INFORMATION = {
    'url': URL,
    'method': METHOD,
    'headers': HEADERS,
}
loop = get_event_loop()
tasks = gather(*[ensure_future(aio_request(REQUEST_INFORMATION))])
tasks.add_done_callback(callback_None)
tasks.add_done_callback(partial(callback, '22'))
loop.run_until_complete(tasks)
print(tasks.result())

tasks.add_done_callback(callback_None)

方法一,通过tasks的函数add_done_callback函数, 传入你所写的回调函数,每当有函数跑完的await的地方,就会调用回调函数,而future则是你一开始创建的future对象,所以打印future.result()就能看到,是你想要的到的返回值

tasks.add_done_callback(partial(callback, ‘22’))

方法二,通过定义回调函数,当你想要传递参数的时候,也可以这样写,从functools导入partial, 因为partial填入的参数位置是第一位,所以要将future放在最后就好了,这样就可以解决传参问题了

tasks.result()

方法三,从tasks拿到加入gather的所有函数的返回值


闭包

为什么要说闭包呢,因为回调函数的原理类似于闭包。

def add(a, b):
	def show(result):
		print(result)
	return show(result)

show就相当于一个闭包,是内置的一种方法,当要传入一个自定义函数的时候就可以这样写

def add(a, b, func==None):
	def show(result):
		print(result)
	if not func:
		return show(result)
	else:
		return func(result)

如果没传入函数就执行内置闭包函数,否则执行外部提供的函数。这就有点像回调函数的味道了是把。
因为有些情况下,调用函数不能直接拿到返回值,例如异步的情况下,但因为每个用户想要间接拿到返回值的方式不一样,有的用queue有的用redis有的直接print,用闭包函数就可以通过传入一个自定义回调函数,就可以兼容用户的不同需求。有了这种情况后,用户就不用进去源码查看大堆的代码找到代码位置,再去定义闭包函数了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值