繁体   English   中英

python中的异步函数调用

[英]Async function call in python

在python中,我想在创建线程的类中创建一个异步方法而不会阻塞主线程。 新线程结束后,我从该函数/线程返回一个值。

例如,该类用于从网页检索某些信息。 我想在下载页面并返回对象的函数中运行并行处理。

class WebDown:
    def display(self, url):
        print 'display(): ' + content

    def download(self, url):
        thread = Thread(target=self.get_info)
        # thread join
        print 'download(): ' + content
        # return the info

    def get_info(self, url):
        # download page
        # retrieve info
        return info

if __name__ == '__main__':
    wd = WebDown()
    ret = wd.download('http://...')
    wd.display('http://...')

在此示例中,为了在调用显示其他信息的display()之后,依次调用download()来检索信息。 打印输出应为

display(): foo, bar, ....
download(): blue, red, ....

用python编写异步,非阻塞代码的一种方法涉及使用Python的Twisted。 Twisted不依赖多线程,而是使用多处理 它为您提供了方便的方法来创建Deferred对象,并向它们添加回调和errbacks。 您提供的示例在Twisted中看起来像这样,我使用的是treq (Twisted Requests)库,该库使生成请求更快,更轻松:

from treq import get
from twisted.internet import reactor

class WebAsync(object):
    def download(self, url):
        request = get(url)
        request.addCallback(self.deliver_body)

    def deliver_body(self, response):
        deferred = response.text()
        deferred.addCallback(self.display)
        return deferred

    def display(self, response_body):
        print response_body
        reactor.stop()

if __name__ == "__main__":
    web_client = WebAsync()
    web_client.download("http://httpbin.org/html")
    reactor.run()

'download'和'deliver_body'方法都返回deferred ,您将向它们添加回调,这些回调将在结果可用时执行。

我只是使用requestgevent叫做grequests

import grequests
>>> urls = [
    'http://...',
    'http://...'
]
>>> rs = (grequests.get(u) for u in urls)
>>> grequests.map(rs)
[<Response [200]>, <Response [200]>]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM