2009-05-24 7 views
2

J'ai deux classes Python, appelez-les "C1" et "C2". Inside C1 est une fonction nommée "F1" et à l'intérieur C2 est une fonction nommée "F2". Existe-t-il un moyen d'exécuter F2 chaque fois que F1 est exécuté sans faire un appel direct à F2 à partir de F1? Existe-t-il un autre mécanisme permettant de savoir quand une fonction de l'intérieur d'une autre classe a été appelée?Comment savoir lorsqu'une fonction d'une autre classe a été appelée

Je me réjouis de toute suggestion, mais je voudrais savoir d'une certaine façon d'y parvenir sans faire une instance de C2 en C1.

+0

+1 pour la bonne description, nouvel utilisateur. –

+3

Qu'essayez-vous d'accomplir? Quel est le problème de l'appeler directement. On dirait que vous voulez quelque chose comme un événement sur appel sur la fonction. Ce qui est quelque peu redondant semble ce que vous avez besoin de faire, vous pouvez coder dans la fonction elle-même. – paan

+1

"créer une instance de C2 à l'intérieur de C1"?Que veux-tu dire par là? Pouvez-vous donner un exemple de ce dont vous parlez? En Python, tout est une référence, donc cette instance "à l'intérieur" d'une autre instance ne veut pas dire grand chose. Qu'est-ce qui vous inquiète? –

Répondre

2

Je crois que ce que vous essayez de faire entrerait dans le domaine de Aspect Oriented Programming. Cependant, je n'ai jamais utilisé cette méthodologie et je ne sais même pas si elle peut/a été implémentée en Python.

Modifier Je viens de jeter un coup d'oeil au lien que j'ai fourni et j'ai vu qu'il y a 8 Python implementations mentionné. Ainsi, le travail a déjà été fait pour vous :-)

2

Vous pouvez faire de la programmation orientée aspect avec les décorateurs de fonction et de méthode depuis Python 2.2:

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

Cela dépend vraiment pourquoi vous ne voulez pas appeler F2 directement depuis F1. Vous pouvez toujours créer une troisième classe (C3) qui encapsule à la fois C1 et C2. Lorsque F3 est appelé, il appelle à la fois F1 et F2. Ceci est connu comme le modèle Mediator - http://en.wikipedia.org/wiki/Mediator_pattern

0

Vous attrapez tous les accès à F1 avec __getattr__. Cela vous permettra de faire un traitement supplémentaire ou de retourner votre propre fonction à la place de F1

class C1: 
    def __getattr__(self,name): 
    if name == 'F1': C2.F2() 
    return self[name] 

Je dois vous avertir que ce appellera C2.F2 même si F1 est uniquement accessible (pas courir). Il est rare mais pas impossible que la F1 soit simplement accessible à d'autres fins comme f = myC1.F1. Pour exécuter F2 uniquement sur un appel de F1, vous devez développer cet exemple pour combiner F2 avec l'objet fonction retourné. en d'autres termes:

def F1F2(): 
    self.F1() 
    C2.F2() 
return F1F2 
3

Vous pouvez écrire un petit décorateur assistant qui fera l'appel pour vous. L'avantage est qu'il est facile de dire qui va appeler quoi en regardant le code. Et vous pouvez ajouter autant d'appels de fonctions que vous le souhaitez. Il fonctionne comme l'enregistrement d'une fonction de rappel:

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 
1

Ne sachant pas ce que vous essayez de réaliser, je vous suggère de jeter un oeil à pydispatcher. Il vous permet d'implémenter le modèle Observer

Fondamentalement, vous enregistrez F2 avec le répartiteur de sorte qu'il sera appelé quand un «signal» spécifique est émis. Votre F1 "émet un signal" qui dit "On m'a appelé". Le répartiteur appelle alors F2 (ou n'importe quel nombre de fonctions qui se sont enregistrées avec ce signal particulier). C'est vraiment plus simple que ça en a l'air, facile à utiliser, et découpler votre code (F1 n'a pas besoin de savoir à propos de F2).

(arhh .. Je suis un nouvel utilisateur et non autorisé à inclure des hyperliens, mais pydispatcher est facile à Google pour)

Questions connexes