Python: Dekorieren einer Klassenmethode, die bei der Vererbung überschrieben werden soll

Angenommen, ich habe eine Basisklasse:

class Task: def run(self): #override this! 

Nun möchte ich, dass andere die Task-Klasse unterklassen und die run () -Methode überschreiben:

 class MyTask(Task): def run(self): #successful override! 

Allerdings ist das Problem, dass es eine Logik, die vor und nach der run () -Methode jeder Klasse, die Unterklassen Aufgabe muss stattfinden.

Es scheint, wie eine Möglichkeit, die ich tun könnte, wäre, eine andere Methode in der Basisklasse zu definieren, die dann die run () – Methode aufruft. Allerdings wollte ich fragen, gibt es einen Weg, dies mit Dekorateure zu erreichen? Was wäre die pythonischste Art, dies zu tun?

  • Wie man einen bedingten dekorateur in python 2.6 macht
  • Python, verwirrt in dekorieren und schließen
  • Gibt es einen Dekorateur, um einfach Cache-Funktion Rückgabewerte?
  • Python dekorator argumente mit @ syntax
  • Toggling decorators
  • Wie benutzt man den User_passes_Test Dekorator in klassenbasierten Ansichten?
  • One Solution collect form web for “Python: Dekorieren einer Klassenmethode, die bei der Vererbung überschrieben werden soll”

    Wie in den Kommentaren vorgeschlagen, lassen die Unterklassen überschreiben einen Haken statt run selbst wäre wahrscheinlich am besten:

     class Task(object): def run(self): # before self.do_run() # after class MyTask(Task): def do_run(self): ... task = MyTask() task.run() 

    Allerdings ist dies ein Weg, den Sie es mit einem Klassiker machen könnten :

     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() # prints: # before # after 

    Ein anderer Weg wäre, eine Metaklasse zu benutzen. Der Vorteil der Verwendung einer Metaklasse wäre, dass Unterklassen nicht dekoriert werden müssten. Task könnte eine Instanz der Metaklasse gemacht werden, und dann würden alle Unterklassen von Task die Metaklasse automatisch erben.

     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 class MyTask(Task): def run(self): #successful override! pass task = MyTask() task.run() 
    Python ist die beste Programmiersprache der Welt.