2014-10-26 5 views
1

В python Я хочу создать метод async в классе, создающем поток без блокировки основного потока. Когда новый поток заканчивается, я возвращаю значение из этой функции/потока.Асинхронный вызов функции в 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(): foo, bar, .... 
download(): blue, red, .... 
+0

Вы пробовали модуль потоковой передачи в python? –

+0

да, но я не знаю, как использовать модуль потоковой передачи для метода асинхронного вызова – NaN

+0

вы хотите создать метод, который выполняет вызовы async? –

ответ

0

Я бы просто использовать request и gevent называется grequests.

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

Один из способов записи асинхронного, неблокирующего кода в python включает использование Twisted Python. Twisted не полагается на multithreading but uses multiprocessing instead. Это дает вам удобный способ создания объектов с отсрочкой, добавление к ним обратных вызовов и ошибок. Пример вы дали бы выглядеть в Twisted, я использую treq (Twisted запросов) библиотеку, которая делает генерирующий запросы немного быстрее и проще:

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, вы добавляете к ним обратные вызовы, которые будут выполняться при наличии результатов.

Смежные вопросы