: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], lambda *aa, **kw: getattr(obj, prefix+k[0])(*aa, **kw)
            else:
                raise ValueError()
        else:
            return k, lambda *aa, **kw: getattr(obj, prefix+k)(*aa, **kw)
                      # Use `lambda` to delay evaluation of `getattr`.
                      # I don't want to require definition of all methods.
                      # Let users define only the ones he needs.

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