Skip to content

Instantly share code, notes, and snippets.

@nithinmanne
Created September 16, 2020 18:57
Show Gist options
  • Save nithinmanne/d652704501def31cb3daace5c4d57bf5 to your computer and use it in GitHub Desktop.
Save nithinmanne/d652704501def31cb3daace5c4d57bf5 to your computer and use it in GitHub Desktop.
Code to create a simple registerer.
"""This function returns two functions, the first is used to call by the registered
functions based on the first argument(index or key). The second is a decorator
used to register a new function. The decorator takes a key as argument or if no
argument is provided, it taked the function name as key.
Usage:
call, register = create_registerer()
@register('first')
def a(arg): pass
@register
def b(arg): pass
call('first', arg) # a(arg)
call(1, arg) # a(arg)
call('b', arg) # b(arg)
call(2, arg) # b(arg)
"""
from functools import singledispatch
from itertools import islice
def create_registerer():
@singledispatch
def call(key, *args, **kwargs):
"""Use this function to call a registered function based on key"""
return call.map[key](*args, **kwargs)
@call.register
def _(key: int, *args, **kwargs):
"""Use index rather than the key"""
assert 1 <= key <= len(call.map)
return next(islice(call.map.values(),
key - 1,
len(call.map)))(*args, **kwargs)
call.map = {}
def register_callee(key):
"""Use this decorator to register a callee"""
assert not isinstance(key, int)
def register(callee):
call.map[key] = callee
call.__doc__ += f'\n{len(call.map)}. {key}'
return callee
if callable(key):
creator, key = key, key.__name__
return register(creator)
else:
return register
return call, register_callee
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment