2012-06-13 65 views
0

我有一個相對較大的枚舉,其中每個成員表示一個消息類型。客戶端將收到一條消息,其中包含與枚舉中msg類型關聯的整數值。對於每個msg類型,都會有一個單獨的函數回調來處理msg。使用Python將函數存儲在稀疏數組中

我想通過使用枚舉值映射到回調索引的稀疏數組(或矢量)儘可能快地查找和分派回調。如果數組不能包含函數類型,這在Python中是可行的嗎?

#pseudo code for 'enum' 
class MsgType(object): 
    LOGIN, LOGOUT, HEARTBEAT, ... = range(n) 

#handler class 
class Handler(object): 
    def handleMsg(self, msg): 
     #dispatch msg to specific handler 

    def __onLogin(self, msg): 
     #handle login 

    def __onLogout(self, msg): 
     #handle logout 

更新: 我是不是在我的術語清晰。我現在理解Python字典查找的複雜度爲O(1),這使得它們成爲完美的候選者。謝謝。

+5

1.數組(我想你是指元組或列表)可以保存函數。 2.使用'dict'。 –

+0

@DavidHeffernan在兩點上都完全正確。 Python數組可以保存函數引用,你應該使用'dict'來解決這個問題。 – steveha

+0

@DavidHeffernan我認爲你應該給出這個答案。 –

回答

2
class MsgID(int): 
    pass 

LOGIN = MsgID(0) 
LOGOUT = MsgID(1) 
HEARTBEAT = MsgID(2) 
... # add all other message identifier numbers 

class MsgType(object): 
    def __init__(self, id, data): 
     self.id = id 
     self.data = data 


def login_handler(msg): 
    ... # do something here 

def logout_handler(msg): 
    ... # do something here 

def heartbeat_handler(msg): 
    ... # do something here 


msg_func = { 
    LOGIN : login_handler, 
    LOGOUT : logout_handler, 
    HEARTBEAT : heartbeat_handler, 
    ... 
} 


class Handler(object): 
    def handleMsg(self, msg): 
     try: 
      msg_func[msg.id](msg) # lookup function reference in dict, call function 
     except KeyError: 
      log_error_mesg('message without a handler function: %d' % msg.id) 

這不是嚴格必要的,但我加的int一個子類的消息ID。這樣你可以檢查ID值是否真的是一個ID值,而不是一些隨機的整數。

我假設每封郵件都會有一個ID值,標識它是什麼類型的郵件以及一些數據。 msg_func字典使用MsgID值作爲鍵映射到函數引用。

你可以把所有的功能放在一個類中,但我沒有這樣做;他們只是功能。

+0

感謝steveha,我很欣賞這個迴應,但是我特別想弄清楚如何在一個容器中存儲函數,這個容器可以用一個整數值來索引。 – Graeme

+0

你爲什麼想這樣做?你要通過這樣做來解決什麼問題?請注意,您始終可以構建函數引用的'list',並且也可以使用相同的函數引用來構建'dict',因此您所要求的內容很容易實現。但我沒有看到這一點。 – steveha

+0

哦,你擔心訪問速度。一個'dict()'在Python中非常快;幾乎每當你想要某種稀疏的數據結構時,一個'dict'都是一個很好的解決方案。 – steveha