Python Twisted: дождитесь заполнения переменной другим событием

Я знаю, что скрученный не будет "ждать"... Я работаю с клиентом XMPP для обмена данными с внешним процессом. Я отправляю запрос и должен получить соответствующий ответ. Я использую sendMessage для отправки моего запроса на сервер. Когда сервер отвечает, метод onMessage получит его и проверит, является ли он ответом на запрос (не обязательно тот, который я ищу), и поместит любой ответ в стек. В качестве возврата к моему sendRequest я хочу вернуть результаты, поэтому я хотел бы вытолкнуть ответ на мой запрос из стека и вернуться. Я читал о потоках, отсрочках, обратных вызовах и условных выражениях, перепробовал множество примеров, и ни один из них не работает для меня. Так что мой пример кода здесь очень урезанный псевдокод, чтобы проиллюстрировать мою проблему. Любые советы приветствуются.

class Foo(FooMessageProtocol):
    def __init__(self, *args, **kwargs):
        self.response_stack = dict()
        super(Foo, self).__init__(*args, **kwargs)    


    def sendRequest(self, data):
        self.sendMessage(id, data)
        # I know that this doesn't work, just to illustrate what I would like to do:
        while 1: 
            if self.response_stack.has_key(id):
               break
               return self.response_stack.pop(id) 


    def receiveAnswers(self, msg):
        response = parse(msg)
        self.response_stack[response['id']] = response

person daccle    schedule 03.09.2010    source источник


Ответы (1)


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

Таким образом, код, вызывающий sendRequest, может просто добавить обратный вызов к отложенному, и он будет вызван, когда будет ответ.

Что-то вроде этого (псевдокод):

class Foo(FooMessageProtocol):
    def __init__(self, *args, **kwargs):
        self._deferreds = {}
        super(Foo, self).__init__(*args, **kwargs)    

    def sendRequest(self, data):
        self.sendMessage(id, data)
        d = self._deferreds[id] = defer.Deferred()
        return d

    def receiveAnswers(self, msg):
        response = parse(msg)
        id = response['id']
        if id in self._deferreds:
            self._deferreds.pop(id).callback(response)
person nosklo    schedule 03.09.2010
comment
Спасибо! Две заметки себе: (1) всё есть объект и (2) RTFM минимум дважды! Я не понял всей сути отсрочек, и благодаря вашему примеру и документам я преодолел этот момент и сумел решить проблему. Спасибо! - person daccle; 04.09.2010