from functools import reduce class HookException(Exception): pass class HookMan: hooks = {} def __new__(cls): return reduce(lambda x, y: y(x), cls.hooks, super(HookMan, cls).__new__(cls)) def execute_hooks(self, hook_type, *args, **kwargs): if hook_type not in self.hooks: return for hook in self.hooks[hook_type]: print(f"Executing hook {hook.__name__}") try: hook()(*args, **kwargs) except Exception as exc: raise HookException(exc) @classmethod def add_hook(cls, func, *args, **kwargs): """Adds a hook.""" hook_type = func.hook_type if hook_type in cls.hooks: cls.hooks[hook_type] = cls.hooks[hook_type] + [func] else: cls.hooks[hook_type] = [func] hook = HookMan() # @hook.add_hook # class example_hook: # """Example hook.""" # hook_type = "player_login" # # def __call__(self, *args, **kwargs): # print("Hook player_login,", kwargs) # # hook.execute_hooks("player_login", hello="john")