provides = {} keybindings = {} class Modifiers: shift = 1 meta = 2 def api_provides(name=None): def decorator(f): # Allow optional naming of what it provides fname = name or f.func_name provides[fname] = f # Optional wrapping of the function for a normal decorator def wrapper(*args, **kwargs): return f(*args, **kwargs) return wrapper return decorator def keybinding(key, modifiers): def decorator(f): # A terrible key value, just doing this for demonstration keybindings[str(key) + str(modifiers)] = f # Optional wrapping of the function for a normal decorator def wrapper(*args, **kwargs): return f(*args, **kwargs) return wrapper return decorator class Test(object): def __init__(self): pass @api_provides() def do_something(self): print 'do something' @api_provides('do_something_else') def strange_function_name(self, x): print 'doing something else', x @keybinding('t', [Modifiers.meta, Modifiers.shift]) def command_t(self): print 'called command + shift + t' def api_call(method, *args, **kwargs): return provides[method](*args, **kwargs) def keypress(keys): # You get the picture =] pass def main(): t = Test() print 'Provides:', provides print 'Keybindings:', keybindings api_call('do_something', t) api_call('do_something_else', t, 1337) keypress('M-T') main()