:return:
        a dictionary roughly equivalent to ``{'key1': obj.on_key1, 'key2': obj.on_key2, ...}``,
        but ``obj`` does not have to define all methods. It may define the needed ones only.

    :param obj: the object

    :param keys: a list of keys

    :param prefix: a string to be prepended to keys to make method names

def make_routing_table(obj, keys, prefix='on_'):
    """
    :return:
        a dictionary roughly equivalent to ``{'key1': obj.on_key1, 'key2': obj.on_key2, ...}``,
        but ``obj`` does not have to define all methods. It may define the needed ones only.

    :param obj: the object

    :param keys: a list of keys

    :param prefix: a string to be prepended to keys to make method names
    """
    def maptuple(k):
        if isinstance(k, tuple):
            if len(k) == 2:
                return k
            elif len(k) == 1:
                return k[0], _create_invoker(obj, prefix+k[0])
            else:
                raise ValueError()
        else:
            return k, _create_invoker(obj, prefix+k)

    return dict([maptuple(k) for k in keys])