0

各メンバーがメッセージタイプを表す比較的大きな列挙型があります。クライアントは、列挙型の msg タイプに関連付けられた整数値を含むメッセージを受け取ります。メッセージ タイプごとに、メッセージを処理するための個別の関数コールバックがあります。

列挙値がコールバックのインデックスにマップされるスパース配列 (またはベクトル) を使用して、コールバックのルックアップとディスパッチをできるだけ迅速に行いたいと考えています。配列が関数型を保持できない場合、これは 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) の複雑さを持っていることを理解しており、完璧な候補となっています。ありがとう。

4

1 に答える 1

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値をキーとして使用し、関数参照にマップします。

すべての関数を 1 つのクラスに入れることもできますが、ここではしませんでした。それらは単なる関数です。

于 2012-06-13T19:32:08.920 に答える