2009-04-12 5 views
1

J'ai besoin d'écrire des gestionnaires pour plusieurs types de cas différents (en Python). L'interface pour tous ces types est la même, mais la logique de gestion est différente.L'encapsulation par rapport à l'héritage, aide à faire un choix

Une option serait la définition d'une classe commune qui reçoit le type de gestionnaire particulier comme l'un des paramètres __init__:

class Handler: 
    def __init__ (self, handlerType): 
     self._handlerType = handlerType 
     self._handler = handlerType.handleStuff 

    def handleStuff(self, *args, **kwargs): 
     return self._handler(args, kwargs) 


# case specific handlers 

class Handler_Case1: 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 1' 


class Handler_Case2: 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 2' 



if __name__ == '__main__': 
    handlers = [] 
    handlers.append(Handler(Handler_Case1)) 
    handlers.append(Handler(Handler_Case2)) 
    for h in handlers: 
     h.handleStuff() 

Cependant, il en résulte une TypeError:

TypeError: unbound method handleStuff() must be called with Handler_Case1 instance as first argument (got tuple instance instead)

Une autre option est pour imiter la fonction abstraite, comme indiqué here ("Q: Pouvez-vous implémenter des classes abstraites dans Python dans 0 lignes de code?"):

class Handler: 
    def handleStuff(self, *args, **kwargs): abstract 
    def commonFunction(self): 
     print 'Common function' 


# case specific handlers 

class Handler_Case1(Handler): 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 1' 


class Handler_Case2(Handler): 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 2' 



if __name__ == '__main__': 
    handlers = [] 
    h1 = (Handler_Case1()) 
    h2 = (Handler_Case2()) 
    handlers.append(h1) 
    handlers.append(h2) 
    for h in handlers: 
     h.handleStuff() 
     print 

Donc, en fait, j'ai deux questions:

  1. Laquelle des deux approches est plus pythonique? et
  2. Comment implémenter le premier?

Répondre

4

Je pourrais être absent une intrication subtile dans votre question, mais étant donné votre premier exemple, ce que vous empêche de faire quelque chose comme ceci:

class HandlerCase1(object): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 1" 


class HandlerCase2(object): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 2" 


if __name__ == "__main__": 
    handlers = [] 
    handlers.append(HandlerCase1()) 
    handlers.append(HandlerCase2()) 
    for h in handlers: 
     h.handle_stuff() 

Et si vous voulez que les cours de partager certaines communes (base), y a-t-il quelque chose qui vous empêche de le faire:

class Handler(object): 
    def common_function(self): 
     print "Common function" 


class HandlerCase1(Handler): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 1" 


class HandlerCase2(Handler): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 2" 


if __name__ == "__main__": 
    handlers = [] 
    handlers.append(HandlerCase1()) 
    handlers.append(HandlerCase2()) 
    for h in handlers: 
     h.handle_stuff() 
     h.common_function() 
Questions connexes