2014-10-26 95 views
1

在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, .... 
+0

你有没有尝试过python的线程模块? – 2014-10-26 20:01:51

+0

是的,但我不知道如何使用线程模块调用异步方法 – NaN 2014-10-26 20:03:42

+0

你想创建一个方法来调用异步吗? – 2014-10-26 20:04:09

回答

0

我会简单地使用requestgevent称为​​。

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

在python中编写异步非阻塞代码的一种方法是使用Python的Twisted。扭曲不依赖于multithreading but uses multiprocessing instead。它为您提供了创建Deferred对象的便捷方式,为它们添加了回调函数和errbacks。你给看起来像这样在扭曲的例子,我用这使得生成请求再快一点treq(扭曲的要求)库,更轻松:

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() 

两个“下载”和“deliver_body”方法返回deferreds,您可以添加回调给他们,这些回调将在结果可用时执行。