2009-05-28 5 views
6

Ceci est une suite à la question 912526 - How do I pass lots of variables to and from a function in Python?.Comment utiliser les classes dérivées de la classe de liste Python

Il y a beaucoup de variables qui doivent être transmises dans le programme que j'écris, et d'après ma question précédente, je comprends que je devrais mettre ces variables dans les classes, et ensuite passer les classes. Certaines de ces variables viennent dans des ensembles répétitifs - pour un calcul de film mince, j'ai besoin de suivre les propriétés optiques (indice de réfraction, absorption, épaisseur, etc.) pour un certain nombre de couches.

Est-ce la meilleure façon de stocker des variables de ce type pour créer une classe dérivée d'une liste Python pour stocker l'ensemble des classes qui contiennent chacune les variables pour une seule couche? Et puis placez les fonctions qui traitent de l'ensemble des couches de la classe dérivées de la liste, et les fonctions qui traitent d'une couche spécifique dans cette classe? Y a-t-il une meilleure façon de le faire avec une seule classe?

Je suis en mesure de mettre les choses pour que je puisse accéder à des variables à l'aide statments comme

n1 = layers[5].n 

C'est la meilleure façon de faire, en utilisant les deux approche de classe dans l'exemple suivant, non?

#Test passing values to and from functions 

class Layers(list): 

    def add(self,n,k,comment): 
     self.append(OneLayer(n,k,comment)) 

    def input_string(self): 
     input_string = [] 
     for layer in self: 
      vars = layer.input_string() 
      for var in vars: 
       input_string.append(var) 
     return input_string 

    def set_layers(self,results): 
     for layer,i in enumerate(self): 
      j = i*layer.num_var 
      layer.set_layer(*results[j:j+2]) 

class OneLayer(object): 

    def __init__(self,n,k,comment): 
     self.n = n 
     self.k = k 
     self.comment = comment 

    def input_string(self): 
     return [['f','Index of Refraction',self.n], ['f','Absorption',self.k],['s','Comment',self.comment]] 

    def set_layer(self,n,k,comment): 
     self.n = n; self.k=k; self.comment = comment 

    def num_var(self): 
     return 3 

if __name__ == '__main__': 
    layers = Layers() 

    layers.add(1.0,0.0,'This vacuum sucks') 
    layers.add(1.5,0.0,'BK 7 Glass') 

    print layers[0].n 
    print layers.input_string() 
    layers[1].set_layer(1.77,0.0,'Sapphire') 
    print layers.input_string() 

je reçois la sortie suivante de ce programme de test:

1.0 
[['f', 'Index of Refraction', 1.0], ['f', 'Absorption', 0.0], ['s', 'Comment', 'This vacuum sucks'], ['f', 'Index of Refraction', 1.5], ['f', 'Absorption', 0.0], ['s', 'Comment', 'BK 7 Glass']] 
[['f', 'Index of Refraction', 1.0], ['f', 'Absorption', 0.0], ['s', 'Comment', 'This vacuum sucks'], ['f', 'Index of Refraction', 1.77], ['f', 'Absorption', 0.0], ['s', 'Comment', 'Sapphire']] 
+1

Avez-vous vraiment besoin d'une classe 'Layers' qui hérite de' list'? Utilisez simplement une liste à la place. –

Répondre

9

Il y a plusieurs questions dans votre code:

1. Si vous faites une opération de liste le résultat sera natif liste:

layers1 = Layers() 
layers2 = Layers() 
layers1 + layers2 -> the result will be a native list 

2.Pourquoi définir input_string lorsque vous pouvez remplacer __repr__ ou __str__

3.Pourquoi devez-vous dériver de la liste dans ce cas? Vous avez seulement besoin de dériver de la liste si vous voulez que votre classe se comporte exactement comme une liste. Mais dans votre cas, vous semblez chercher un conteneur. Tout ce que vous devez faire pour obtenir votre classe pour se comporter semblable à une liste est de remplacer certaines méthodes de python spéciales http://docs.python.org/reference/datamodel.html#emulating-container-types

class Layers(object): 
    def __init__(self, container=None): 
     if container is None: 
      container = [] 
     self.container = container 

    def add(self,n,k,comment): 
     self.container.append([n,k,comment]) 

    def __str__(self): 
     return str(self.container) 

    def __repr__(self): 
     return str(self.container) 

    def __getitem__(self, key): 
     return Layers(self.container[key]) 

    def __len__(self): 
     return len(self.container) 

>>> l = Layers() 
>>> l.add(1, 2, 'test') 
>>> l.add(1, 2, 'test') 
>>> l 
[[1, 2, 'test'], [1, 2, 'test']] 
>>> l[0] 
[1, 2, 'test'] 
>>> len(l) 
2 
+0

@hopatcong: Vous pouvez résoudre le premier problème en implémentant la méthode __add__. Voir http://docs.python.org/reference/datamodel.html#emulating-numeric-types. –

+0

Juste un ajout ici, __repr__ est le bon remplacement pour input_string. __str__ est censé être pour une explication informelle/simple - pas une représentation complète de l'objet. – monokrome

+1

Et votre code a un problème: valeur par défaut mutable, voir http://stackoverflow.com/q/1132941/13543 –

Questions connexes