2 Stimmen

Wie kann man feststellen, ob eine Funktion in einer anderen Klasse aufgerufen wurde?

Ich habe zwei Python-Klassen, nennen Sie sie "C1" und "C2". In C1 gibt es eine Funktion namens "F1" und in C2 eine Funktion namens "F2". Gibt es eine Möglichkeit, F2 jedes Mal auszuführen, wenn F1 ausgeführt wird, ohne einen direkten Aufruf von F1 an F2 zu machen? Gibt es einen anderen Mechanismus, mit dem sich feststellen lässt, wann eine Funktion innerhalb einer anderen Klasse aufgerufen wurde?

Ich freue mich über jeden Vorschlag, würde aber gerne wissen, wie man dies erreichen kann, ohne eine Instanz von C2 innerhalb von C1 zu erstellen.

3voto

Nadia Alramli Punkte 105256

Sie können einen kleinen Hilfsdekorator schreiben, der den Anruf für Sie tätigt. Der Vorteil ist, dass man leicht erkennen kann, wer was aufruft, wenn man sich den Code ansieht. Und Sie können so viele Funktionsaufrufe hinzufügen, wie Sie wollen. Es funktioniert wie die Registrierung einer Callback-Funktion:

from functools import wraps

def oncall(call):
    def helper(fun):
        @wraps(fun)
        def wrapper(*args, **kwargs):
            result = fun(*args, **kwargs)
            call()
            return result
        return wrapper
    return helper

class c1:
   @classmethod
   def f1(cls):
      print 'f1'

class c2:
   @classmethod
   @oncall(c1.f1)
   def f2(cls):
      print 'f2'

>>> c2.f2()
f2
f1
>>> c1.f1()
f1

2voto

Peter M Punkte 7213

Ich glaube, dass das, was Sie zu tun versuchen, in den Bereich der Aspektorientierte Programmierung . Ich habe diese Methode jedoch noch nie verwendet und weiß nicht einmal, ob sie in Python implementiert werden kann oder wurde.

bearbeiten Ich habe gerade einen Blick auf den von mir angegebenen Link geworfen und gesehen, dass es 8 Python-Implementierungen erwähnt. Die harte Arbeit wurde also bereits für Sie erledigt :-)

2voto

duffymo Punkte 298898

Seit Python 2.2 können Sie mit Funktions- und Methodendekoratoren aspektorientiert programmieren:

@decorator(decorator_args)
def functionToBeDecorated(function_args) :
    pass

2voto

James Punkte 431

Es kommt darauf an, warum Sie F2 nicht direkt aus F1 aufrufen wollen. Sie könnten immer eine dritte Klasse (C3) erstellen, die sowohl C1 als auch C2 kapselt. Wenn F3 aufgerufen wird, ruft es sowohl F1 als auch F2 auf. Dies wird als Mediator-Muster bezeichnet. http://en.wikipedia.org/wiki/Mediator_pattern

1voto

arcanum Punkte 697

Da ich nicht weiß, was Sie zu erreichen versuchen, würde ich vorschlagen, einen Blick auf pydispatcher zu werfen. Es ermöglicht Ihnen, die Beobachter-Muster zu implementieren

Im Grunde registrieren Sie F2 beim Dispatcher, so dass es aufgerufen wird, wenn ein bestimmtes "Signal" ausgegeben wird. Ihr F1 "sendet ein Signal", das besagt: "Ich wurde gerufen". Der Dispatcher ruft dann F2 auf (oder eine beliebige Anzahl von Funktionen, die sich für dieses bestimmte Signal registriert haben). Es ist wirklich einfacher, als es klingt, leicht zu bedienen und entkoppelt Ihren Code (F1 muss nicht über F2 wissen).

(arhh.. ich bin ein neuer Benutzer und darf keine Hyperlinks einfügen, aber pydispatcher ist leicht zu googeln)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X