Система событий в Python

Также было бы полезно рассмотреть то, что они делают с семантической точки зрения:

_.assign

   will assign the values of the properties of its second parameter and so on,
   as properties with the same name of the first parameter. (shallow copy & override)

_.merge

   merge is like assign but does not assign objects but replicates them instead.
  (deep copy)

_.defaults

   provides default values for missing values.
   so will assign only values for keys that do not exist yet in the source.

_.defaultsDeep

   works like _defaults but like merge will not simply copy objects
   and will use recursion instead.

Я считаю, что научиться думать об этих методах с семантической точки зрения позволит вам лучше «угадать», что будет поведение для всех различных сценариев существующих и несуществующих ценностей.

180
задан Josip 7 July 2009 в 03:00
поделиться

6 ответов

Вот еще один модуль для рассмотрения. Этот вариант подходит для более требовательных приложений.

Py-notify - это пакет Python. предоставление инструментов для реализации Шаблон программирования наблюдателя. Эти инструменты включают сигналы, условия и переменные.

Сигналы - это списки обработчиков, которые вызывается, когда издается сигнал. Условия в основном логические переменные вместе с сигналом, который излучается, когда состояние состояния изменения. Их можно комбинировать с помощью стандартные логические операторы (не, и, др.) в сложные условия. Переменные, в отличие от условий, могут иметь любой объект Python, а не только логические, но их нельзя объединить.

2
ответ дан 23 November 2019 в 06:12
поделиться

Я использую zope.event . Это самые голые кости, которые вы можете себе представить. :-) Фактически, вот полный исходный код:

subscribers = []

def notify(event):
    for subscriber in subscribers:
        subscriber(event)

Обратите внимание, что, например, вы не можете отправлять сообщения между процессами. Это не система обмена сообщениями, просто система событий, ни больше, ни меньше.

20
ответ дан 23 November 2019 в 06:12
поделиться

Я нашел этот небольшой сценарий на Ценных уроках . Кажется, у него как раз то, что мне нужно, соотношение простота / мощность. Питер Тэтчер является автором следующего кода (лицензирование не упоминается).

class Event:
    def __init__(self):
        self.handlers = set()

    def handle(self, handler):
        self.handlers.add(handler)
        return self

    def unhandle(self, handler):
        try:
            self.handlers.remove(handler)
        except:
            raise ValueError("Handler is not handling this event, so cannot unhandle it.")
        return self

    def fire(self, *args, **kargs):
        for handler in self.handlers:
            handler(*args, **kargs)

    def getHandlerCount(self):
        return len(self.handlers)

    __iadd__ = handle
    __isub__ = unhandle
    __call__ = fire
    __len__  = getHandlerCount

class MockFileWatcher:
    def __init__(self):
        self.fileChanged = Event()

    def watchFiles(self):
        source_path = "foo"
        self.fileChanged(source_path)

def log_file_change(source_path):
    print "%r changed." % (source_path,)

def log_file_change2(source_path):
    print "%r changed!" % (source_path,)

watcher              = MockFileWatcher()
watcher.fileChanged += log_file_change2
watcher.fileChanged += log_file_change
watcher.fileChanged -= log_file_change2
watcher.watchFiles()
14
ответ дан 23 November 2019 в 06:12
поделиться

Если я пишу код в pyQt, я использую парадигму сокетов / сигналов QT, то же самое для django

Если Я выполняю асинхронный ввод-вывод. Я использую собственный модуль выбора

. Если я использую синтаксический анализатор SAX python, я использую API событий, предоставляемый SAX. Похоже, я стал жертвой базового API: -)

Может быть, вам стоит спросить себя, чего вы ждете от фреймворка / модуля событий. Лично я предпочитаю использовать парадигму Socket / Signal от QT. дополнительную информацию об этом можно найти здесь

3
ответ дан 23 November 2019 в 06:12
поделиться

Мы используем EventHook, как это было предложено Майклом Фурдом в его Шаблон событий :

Просто добавьте EventHooks в свои классы с помощью:

class MyBroadcaster()
    def __init__():
        self.onChange = EventHook()

theBroadcaster = MyBroadcaster()

# add a listener to the event
theBroadcaster.onChange += myFunction

# remove listener from the event
theBroadcaster.onChange -= myFunction

# fire event
theBroadcaster.onChange.fire()

Мы добавили функциональность для удаления всех прослушивателей из объекта в класс Michaels и получили следующее:

class EventHook(object):

    def __init__(self):
        self.__handlers = []

    def __iadd__(self, handler):
        self.__handlers.append(handler)
        return self

    def __isub__(self, handler):
        self.__handlers.remove(handler)
        return self

    def fire(self, *args, **keywargs):
        for handler in self.__handlers:
            handler(*args, **keywargs)

    def clearObjectHandlers(self, inObject):
        for theHandler in self.__handlers:
            if theHandler.im_self == inObject:
                self -= theHandler
64
ответ дан 23 November 2019 в 06:12
поделиться

Я делал это так:

class Event(list):
    """Event subscription.

    A list of callable objects. Calling an instance of this will cause a
    call to each item in the list in ascending order by index.

    Example Usage:
    >>> def f(x):
    ...     print 'f(%s)' % x
    >>> def g(x):
    ...     print 'g(%s)' % x
    >>> e = Event()
    >>> e()
    >>> e.append(f)
    >>> e(123)
    f(123)
    >>> e.remove(f)
    >>> e()
    >>> e += (f, g)
    >>> e(10)
    f(10)
    g(10)
    >>> del e[0]
    >>> e(2)
    g(2)

    """
    def __call__(self, *args, **kwargs):
        for f in self:
            f(*args, **kwargs)

    def __repr__(self):
        return "Event(%s)" % list.__repr__(self)

Однако, как и во всем остальном, что я видел, для этого нет ни авто-генерируемого пидока, ни подписей, что действительно отстойно.

90
ответ дан 23 November 2019 в 06:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: