As suggested in the comments, letting subclasses override the hook instead of run
itself is probably better:
class Task(object): def run(self):
However, this is one way to do this using the class decorator:
def decorate_run(cls): run = getattr(cls, 'run') def new_run(self): print('before') run(self) print('after') setattr(cls, 'run', new_run) return cls class Task(object): pass @decorate_run class MyTask(Task): def run(self): pass task = MyTask() task.run()
Another way would be to use a metaclass. The advantage of using a metaclass would be that subclasses did not need to be decorated. Task
could be made an instance of a metaclass, and then all subclasses of Task
inherit the metaclass automatically.
class MetaTask(type): def __init__(cls, name, bases, clsdict): if 'run' in clsdict: def new_run(self): print('before') clsdict['run'](self) print('after') setattr(cls, 'run', new_run) class Task(object, metaclass=MetaTask):
source share