2013-08-26 97 views
0

我想創建Class結構,其中流程由事件生成進行控制。爲此,我做了以下內容:在python中引發異步事件

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 

不過,我的問題是,基本上所有這些事件都是函數調用和shortwhile後,我構建一個巨大的遞歸調用堆棧。我如何在通知事件的同時退出函數,或者在後臺線程上繼續運行現有函數。

+0

可以包括使用這些類的一些代碼? – Claudiu

+0

爲什麼你使用類屬性和類方法,而不是有一個普通的實例,或只是使全局?這聽起來像你正試圖用Python編寫Java。 – abarnert

回答

0

,你可以:

  • 使用ThreadPools。與進程池相同的界面,但從multiprocessing.pool導入,如from multiprocessing.pool import ThreadPool

    您可以將事件名稱和參數發送到線程處理的池。 這可能會阻塞隊列是否已滿。

  • 在數據庫中創建一個簡單的事件隊列(django模型),並使用單獨的進程/線程來處理事件。這不會阻塞,因爲您可以大多數情況下始終將新對象添加到數據庫。

  • 看看像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() 
+0

你可能會舉一些簡單的例子。順便說一下,我還嘗試了一個名爲axel.events的輕量級庫,該庫被認爲可以用於新線程。 – user1131925

+0

新增'''ThreadPool'''示例。 –

+0

對搜索者來說,使用廣泛使用的'celery'示例也是非常有用的。 –