Скрученный реактор запускается несколько раз в одной программе? - PullRequest
3 голосов
/ 29 апреля 2011

Можно ли запустить реактор более одного раза в одной и той же программе? Предположим, вы хотите инкапсулировать витую функциональность внутри метода для целей API.

Например, mymodule.py выглядит так:

  1 from twisted.web.client import getPage
  2 from twisted.internet import reactor
  3 
  4 def _result(r):
  5     print r
  6     reactor.stop()
  7 
  8 def _error(e):
  9     print e
 10     reactor.stop()
 11 
 12 def getGoogle():
 13     d = getPage('http://www.google.com')
 14     d.addCallbacks(_result, _error)
 15     reactor.run()
 16 
 17 def getYahoo():
 18     d = getPage('http://www.yahoo.com')
 19     d.addCallbacks(_result, _error)
 20     reactor.run()
 21 

main.py выглядит так:

  1 import mymodule
  2 
  3 getGoogle()
  4 getYahoo()

Ответы [ 2 ]

6 голосов
/ 30 апреля 2011

Более простое решение, которое не требует от вас управления счетчиком:

from twisted.internet import reactor, defer
from twisted.web.client import getPage

def printPage(page):
    print page

def printError(err):
    print err

urls = ['http://www.google.com',
        'http://www.example.com']

jobs = []
for url in urls:
    jobs.append(getPage(url).addCallbacks(printPage,
                                          printError))

def done(ignored):
    reactor.stop()
defer.gatherResults(jobs).addCallback(done)

reactor.run()

Вам следует взглянуть здесь на то, что обеспечивается отложенным API, потому что оно будетсэкономить много времени и упростить отладку кода.

6 голосов
/ 29 апреля 2011

Вот еще один способ упорядочить ваш код, используя однопоточную природу Twisted: поставьте в очередь все URL, которые вы хотите обработать, запустите реактор и уменьшите счетчик при завершении каждого запроса. Когда счетчик достигнет нуля, остановите реактор, который выдаст результаты:

from twisted.web.client import getPage
from twisted.internet import reactor

class Getter(object):

    def __init__(self):
        self._sequence = 0
        self._results = []
        self._errors = []

    def add(self, url):
        d = getPage(url)
        d.addCallbacks(self._on_success, self._on_error)
        d.addCallback(self._on_finish)
        self._sequence += 1

    def _on_finish(self, *narg):
        self._sequence -= 1
        if not self._sequence:
            reactor.stop()

    _on_success = lambda self, *res: self._results.append(res)
    _on_error = lambda self, *err: self._errors.append(err)

    def run(self):
        reactor.run()
        return self._results, self._errors

g = Getter()
for url in ('http://www.google.com', 'http://www.yahoo.com', 'idontexist'):
    g.add(url)
results, errors = g.run()
print results
print errors
...