2009-05-28 9 views
6

To jest kontynuacja pytania 912526 - How do I pass lots of variables to and from a function in Python?.Jak używać klas wyprowadzonych z listy klas Pythona

Istnieje wiele zmiennych, które muszą zostać przekazane w programie, który piszę, i z mojego poprzedniego pytania rozumiem, że powinienem umieścić te zmienne w klasach, a następnie omijać klasy.

Niektóre z tych zmiennych występują w zestawach powtarzalnych - w przypadku obliczeń cienkowarstwowych należy śledzić właściwości optyczne (współczynnik załamania, pochłaniania, grubości itp.) Dla wielu warstw.

Czy najlepiej zapisać takie zmienne, aby utworzyć klasę wyprowadzoną z listy Pythona, aby przechowywać zestaw klas, z których każda zawiera zmienne dla pojedynczej warstwy? A następnie umieścić funkcje, które dotyczą zestawu warstw w klasie, wyprowadzone z listy oraz funkcje, które dotyczą konkretnej warstwy w tej klasie? Czy istnieje lepszy sposób na zrobienie tego z jedną klasą?

Stosując podejście dwie klasy w poniższym przykładzie, jestem w stanie ustawić rzeczy tak, że można uzyskać dostęp do zmiennych przy użyciu statments jak

n1 = layers[5].n 

Jest to najlepszy sposób, aby to zrobić, prawda?

#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() 

otrzymuję następujący wyjście z tego programu testowego:

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

Czy naprawdę potrzebujemy klasę 'Layers' która dziedziczy' list'? Po prostu użyj listy. –

Odpowiedz

9

Istnieje kilka kwestii w kodzie:

1.If dokonać jakiejkolwiek operacji lista wynik będzie rodem lista:

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

2.Why określić input_string kiedy można zastąpić __repr__ lub __str__

3.Dlaczego w tym przypadku trzeba jeszcze wyprowadzać z listy? Musisz tylko czerpać z listy, jeśli chcesz, aby twoja klasa zachowywała się dokładnie jak lista. Ale w twoim przypadku wygląda na to, że szukasz pojemnika. Wszystko, co trzeba zrobić, aby uzyskać klasa zachowuje się podobnie do listy jest przesłonić pewne specjalne metody python 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: Możesz naprawić pierwszy problem, wdrażając metodę __add__. Zobacz http://docs.python.org/reference/datamodel.html#emulating-numeric- typeses. –

+0

Tylko tutaj, __repr__ jest poprawnym zamiennikiem dla input_string. __str__ ma na celu nieformalne/proste wyjaśnienie - nie pełną reprezentację obiektu. – monokrome

+1

Twój kod zawiera problem: zmienną wartość domyślną, patrz http://stackoverflow.com/q/1132941/13543 –

Powiązane problemy