2009-09-02 4 views
4

J'ai deux classes que je voudrais fusionner en un composite. Ces deux classes continueront à être utilisées de manière autonome et je ne veux pas les modifier. Pour certaines raisons, je souhaite laisser ma classe composite créer les objets. Je pense à quelque chose comme le code ci-dessous (c'est juste un exemple) mais je pense que c'est complexe et je ne l'aime pas beaucoup. Je suppose qu'il pourrait être amélioré par quelques techniques et astuces que j'ignore.Comment créer des objets dynamiquement de façon élégante en python?

Veuillez noter que le composite est conçu pour gérer un grand nombre de classes différentes avec différentes signatures de constructeur.

Que recommanderiez-vous pour améliorer ce code?

class Parent: 
    def __init__(self, x): 
     self.x = x 

class A(Parent): 
    def __init__(self, x, a="a", b="b", c="c"): 
     Parent.__init__(self, x) 
     self.a, self.b, self.c = a, b, c 

    def do(self): 
     print self.x, self.a, self.b, self.c 

class D(Parent): 
    def __init__(self, x, d): 
     Parent.__init__(self, x) 
     self.d = d 

    def do(self): 
     print self.x, self.d 

class Composite(Parent): 
    def __init__(self, x, list_of_classes, list_of_args): 
     Parent.__init__(self, x) 
     self._objs = [] 
     for i in xrange(len(list_of_classes)): 
      self._objs.append(self._make_object(list_of_classes[i], list_of_args[i])) 

    def _make_object(self, the_class, the_args): 
     if the_class is A: 
      a = the_args[0] if len(the_args)>0 else "a" 
      b = the_args[1] if len(the_args)>1 else "b" 
      c = the_args[2] if len(the_args)>2 else "c" 
      return the_class(self.x, a, b, c) 
     if the_class is D: 
      return the_class(self.x, the_args[0]) 

    def do(self): 
     for o in self._objs: o.do() 


compo = Composite("x", [A, D, A], [(), ("hello",), ("A", "B", "C")]) 
compo.do() 
+0

Parlez-vous des Meta Classes? http://www.ibm.com/developerworks/linux/library/l-pymeta.html – voyager

+0

* Les métaclasses sont plus magiques que 99% des utilisateurs devraient s'inquiéter. Si vous vous demandez si vous en avez besoin, ce n'est pas le cas (les personnes qui en ont réellement besoin savent avec certitude qu'elles en ont besoin et n'ont pas besoin d'explications sur les raisons) *. - Tim Peters – voyager

+0

Je ne sais pas si la métaclasse peut être une solution à ce problème. Je ne suis pas très familier avec ce concept. Je regarderai le lien que vous avez donné avec soin. Merci – luc

Répondre

3

Vous pouvez le raccourcir en supprimant de vérification de type _make_object, et laisser les constructeurs de classe prennent en charge les arguments par défaut, par exemple Cela vous permet également de l'utiliser avec de nouvelles classes sans modifier son code.

+0

'if isinstance (the_class, Parent .__ class__)' devrait être remplacé par 'if issubclass (the_class, Parent)'. sauf cette petite correction, cela fonctionne très bien et correspond au type d'amélioration que je recherche. Merci – luc

Questions connexes