Сигнал Python между функциями для удаления занятого ожидания

Я просто пытаюсь реализовать простой шаблон Observer в Python и сталкиваюсь с проблемой. Это мой код:

class Observable:
    def __init__(self):
    self.__observers = []

    def register_observer(self, observer):
        self.__observers.append(observer)

    def notify_observers(self, data):
        for observer in self.__observers:
            observer.notify(self, data)

class Observer:

    def __init__(self, observable):
        observable.register_observer(self)
        self.data_present = False
        self.data = ''

    def notify(self, observable, data):
        self.data_present = True
        self.data = data

    def wait(self):
        while True:
            if not self.data_present:
                time.sleep(5)

            else:
                break

        return self.data

Здесь я хотел бы устранить занятое ожидание в Observer.wait() (строка time.sleep(5). Как я, возможно, могу сигнализировать этой функции?

2 ответа

Решение

Вам не нужно иметь wait функционировать на всех - просто делать то, что вам нужно в notify (обработка данных, запись данных, искажение / шпиндель / сворачивание данных, что угодно).

Если вы используете многопоточность, проверьте класс Queue.Queue: он позволяет нескольким потокам синхронизироваться по доступности данных без ожидания занятости - просто имейте notify метод толкать данные в Queue, а также wait может подождать. Обратите внимание, что, вероятно, существует более элегантное решение, использующее некоторые другие функции, имеющиеся в модуле Threading.

Как примечание стороны, вам также не нужно двойное подчеркивание в self.__observers -- просто self.observers Это хорошо.

Ты можешь использовать yield приостановить функцию в одной точке, ожидая какое-то значение (заблокировано, без ожидания ожидания).

def f():
    print('f: i am waiting for something...')
    c = yield
    print('f: i got %s' % c)
    yield None

С другой стороны вы звоните .send(val) возобновить его выполнение:

>>> g=f()
>>> next(g)
f: i am waiting for something...
>>> g.send(123)
f: i got 123
>>>

Обратите внимание на дополнительные yield None в конце f() который предотвращает StopIteration исключение из raiseд, когда вы звоните .send(),

Другие вопросы по тегам