在python中引发异步事件

时间:2013-08-26 17:40:05

标签: python events asynchronous

我想制作类结构,其中流程由事件的生成控制。为此,我做了以下事情:

class MyEvent:  
    EventName_FunctionName = {}

    @classmethod
    def setup(cls, notificationname, functionname):
        if notificationname in MyEvent.EventName_FunctionName.keys():
            MyEvent.EventName_FunctionName[notificationname].append(functionname)
        else:
            MyEvent.EventName_FunctionName[notificationname] = [functionname]

    @classmethod    
    def runonnotification(cls, notificationname, *args):
        thisfunclist = MyEvent.EventName_FunctionName[notificationname]
        for func in thisfunclist:
            if len(args) > 0:
                func(*args)
            else:
                func()

然后以下列方式使用它:

from FirstEventClass import MyEvent
class simpleexample:
    def __init__(self,a = 1, b = 2):
        simpleexample.a = a
        simpleexample.b = b
        MyEvent.setup('greater than 100',self.printerror)
        MyEvent.setup('dont do negative',self.negation)
        MyEvent.setup('many values recieved',self.handlemultipleupdates)


    def updation(self,updateval):
        if updateval > 100:
            MyEvent.runonnotification('greater than 100',updateval)
            self.a = updateval
        if updateval < 0:
            MyEvent.runonnotification('dont do negative')


    def multipleupdates(self, a, b):
        MyEvent.runonnotification('many values recieved', a , b)

    def printerror(self,data):
        print ' something has gone wrong' ,data

    def negation(self):
        print 'negation enter'
        self.a = -self.a

    def handlemultipleupdates(self, a , b):
        print 'wow'
        self.a = a
        self.b = b

然而,我的问题是基本上所有这些事件都是函数调用,并且在一段时间之后,我构建了一大堆递归调用。如何退出函数以及通知事件,或者继续在后台线程上运行现有函数。

1 个答案:

答案 0 :(得分:0)

你可以:

  • 使用ThreadPools。与流程池相同的界面,但从multiprocessing.pool导入,如from multiprocessing.pool import ThreadPool

    您可以将事件名称和参数发送到池中以供线程处理。 如果队列已满,则可能会阻止。

  • 在数据库中创建一个简单的事件队列(django models),并使用单独的进程/线程来处理事件。这不会阻止,因为您通常可以始终向db添加新对象。

  • 查看像celery这样的库,它们可以为您提供可扩展性,并且可以在队列顶部构建整个事件调度程序。

ThreadPool示例:

from collections import defaultdict
from multiprocessing.pool import ThreadPool


class MyEvent:
    handlers = defaultdict(list)
    _pool = ThreadPool(5)

    @classmethod
    def setup(cls, notificationname, functionname):
        cls.handlers[notificationname].append(functionname)

    @classmethod
    def runonnotification(cls, notificationname, *args):
        thisfunclist = cls.handlers[notificationname]
        for func in thisfunclist:
            cls._pool.apply_async(func, args=args)


class SimpleExample(object):
    def __init__(self, a=1, b=2):
        SimpleExample.a = a
        SimpleExample.b = b
        MyEvent.setup('greater than 100', self.printerror)
        MyEvent.setup('dont do negative', self.negation)
        MyEvent.setup('many values recieved', self.handlemultipleupdates)

    def updation(self, updateval):
        if updateval > 100:
            MyEvent.runonnotification('greater than 100', updateval)
            self.a = updateval
        if updateval < 0:
            MyEvent.runonnotification('dont do negative')

    def multipleupdates(self, a, b):
        MyEvent.runonnotification('many values recieved', a, b)

    def printerror(self, data):
        print 'something has gone wrong ', data

    def negation(self):
        print 'negation enter'
        self.a = -self.a

    def handlemultipleupdates(self, a, b):
        print 'wow'
        self.a = a
        self.b = b

s = SimpleExample()
for x in [-50, 0, 1, 50, 70, 101]:
    s.updation(x)

MyEvent._pool.close()
MyEvent._pool.join()