2011-01-26 2 views
0

J'ai une classe avec deux méthodes A et B. La classe sera sous-classée. Existe-t-il une manière élégante de faire en sorte que B() ne soit appelé que sur un objet de la classe à l'intérieur de la méthode A()? Nous allons le contraindre et dire que A() n'est appelé qu'à un endroit mais que les sous-classes implémentent A() et peuvent éventuellement appeler B() à l'intérieur de celui-ci. Une façon dont j'ai pensé faire ceci était d'encapsuler l'appel A() avec la définition d'une variable globale qui dit que c'est bon d'appeler B(), et B() vérifierait cette variable quand elle est invoquée. Cela ne semble pas élégant cependant.python: appliquer une méthode de classe uniquement à partir d'une autre méthode de classe?

Des suggestions?

+1

Assurez 'B' privé en ajoutant un underscore donc c'est '_B'. Cela dit aux gens que c'est une méthode privée. Je ne pense pas qu'il existe un moyen facile ou même fiable de faire ce que vous voulez en Python. – martineau

+1

Il semble également que, du point de vue de la conception de POO, votre classe de base en sait trop sur les classes qui en seront dérivées. – martineau

+1

Ajouter un soulignement pour signifier "privé", et supposer que les personnes qui utilisent cet objet sont intelligents, puis passer à des problèmes plus importants. –

Répondre

2

Bien que je ne recommande pas la pratique, voici une façon dont il pourrait être fait en utilisant sys._getframe():

import sys 

class Base(object): 
    def A(self): 
     print ' in method A() of a {} instance'.format(self.__class__.__name__) 

    def B(self): 
     print ' in method B() of a {} instance'.format(self.__class__.__name__) 
     if sys._getframe(1).f_code.co_name != 'A': 
      print ' caller is not A(), aborting' 
      return 
     print ' called from A(), continuing execution...' 

class Derived(Base): 
    def A(self): 
     print " in method A() of a {} instance".format(self.__class__.__name__) 
     print ' calling self.B() from A()' 
     self.B() 

print '== running tests ==' 
base = Base() 
print 'calling base.A()' 
base.A() 
print 'calling base.B()' 
base.B() 
derived = Derived() 
print 'calling derived.A()' 
derived.A() 
print 'calling derived.B()' 
derived.B() 

La sortie:

== running tests == 
calling base.A() 
    in method A() of a Base instance 
calling base.B() 
    in method B() of a Base instance 
    caller is not A(), aborting 
calling derived.A() 
    in method A() of a Derived instance 
    calling self.B() from A() 
    in method B() of a Derived instance 
    called from A(), continuing execution... 
calling derived.B() 
    in method B() of a Derived instance 
    caller is not A(), aborting 
5

Les méthodes privées réelles sont un mal. Marquez votre méthode comme interne en ajoutant un soulignement principal. Cela indique aux programmeurs de ne pas l'utiliser à moins qu'ils ne sachent ce qu'ils font.

+0

Pourriez-vous élaborer à ce sujet? Quel est le problème avec les méthodes privées? – Makis

+0

@Makis: Vous empêchez les gens de les appeler, et s'ils doivent ensuite les appeler, vous leur rendez la vie difficile sans raison. Pour une explication plus longue, j'ai cette réponse: http://stackoverflow.com/questions/4683937/the-use-of-getters-and-setters-for-different-programming-languages/4684469#4684469 –

+0

Pourquoi les autres devraient-ils être capable d'appeler des fonctions internes? Les fonctions statiques en C sont-elles également mauvaises? – Makis

Questions connexes