Foros del Web » Programando para Internet » Python »

problema con clases

Estas en el tema de problema con clases en el foro de Python en Foros del Web. buenas tengo un pequeño problema a la hora de reescribir un parametro en un clase que hereda sus otros parametros de una clase superior.. para ...
  #1 (permalink)  
Antiguo 06/08/2009, 23:08
AxL456
Invitado
 
Mensajes: n/a
Puntos:
problema con clases

buenas tengo un pequeño problema a la hora de reescribir un parametro en un clase que hereda sus otros parametros de una clase superior..

para que me entiendan mejor aqui dejo el codigo:

Código python:
Ver original
  1. import scipy as sp
  2. import scipy.linalg as linalg
  3.  
  4. class solution:
  5.     def __init__(self):
  6.         self.feed_flow = 70.0
  7.         self.feed = sp.array([0.15,0.25,0.4,0.2])
  8.         self.comp_names = ("xylene", "styrene", "toluene", "benzene")
  9.         self.var=("D_1", "B_1", "D_2", "B_2")
  10.         self.xylene = sp.array([0.07,0.18,0.15,0.24])
  11.         self.styrene = sp.array([0.04,0.24,0.1,0.65])
  12.         self.toluene = sp.array([0.54,0.42,0.54,0.1])
  13.         self.benzene = sp.array([0.35,0.16,0.21,0.01])
  14.         T0_comp_frac = self.feed_flow * self.feed    # component fraction on first tower (T0)
  15.         self.comp_eq = sp.array([self.xylene, self.styrene,
  16.                                  self.toluene, self.benzene]) #components linear equations
  17.         self.solve= sp.array(linalg.solve(self.comp_eq, T0_comp_frac))
  18.         self.D = self.solve[0] + self.solve[1]
  19.         self.B = self.solve[2] + self.solve[3]
  20.        
  21.     def comp(self):
  22.         print "D= %s" % self.D
  23.         print "B= %s" % self.B
  24.         for i in range(len(self.var)):
  25.                 print self.var[i], "=", self.solve[i]
  26.         flowname= ("D","B")
  27.         x = 0
  28.         while x<= 3:
  29.             y=0
  30.             z=0
  31.             while y<=2:
  32.                 temp = (self.comp_eq[x,y]*self.solve[y] +
  33.                         self.comp_eq[x,y+1]*self.solve[y+1])/(self.solve[y]+self.solve[y+1])
  34.                 y+=2
  35.                 print self.comp_names[x]+ " in "+ flowname[z]+" = ", temp
  36.                 z+=1
  37.             x+=1
  38.    
  39. class solution2(solution):
  40.     def __init__(self, percent):
  41.         self.feed_flow = 70.0 - 70.0 * percent
  42.    
  43.        
  44. if __name__=="__main__":
  45.     solution=solution()
  46.     solution.comp()
  47.     print "*" * 80
  48.     percent = 0.01
  49.     solution2=solution2(0.01)
  50.     solution2.comp()

el problema lo tengo es exactamente en esta parte del codigo:
Código Python:
Ver original
  1. class solution2(solution):
  2.     def __init__(self, percent):
  3.         self.feed_flow = 70.0 - 70.0 * percent

lo que deseo hacer es especificar una clase "hijo" que herede todos los atributos de la clase "padre" solution menos el parametro feed_flow


el problema es que me manda este error:
Código:
Traceback (most recent call last):
  File "C:\Python25\destilacion3.py", line 50, in <module>
    solution2.comp()
  File "C:\Python25\destilacion3.py", line 22, in comp
    print "D= %s" % self.D
AttributeError: solution2 instance has no attribute 'D'
por lo que entiendo me esta indicando que al ejecutar la funcion comp() dentro de la clase solution2 no encuentra el parametro self.D

lo que no entiendo es porque ocurre este problema si supuestamente la clase solution2 hereda los parametros de la clase solution

hasta los momentos he logrado que el codigo corra adecuadamente reescribiendo TODOS los parametros de la clase base en solution2 de la siguiente manera
Código Python:
Ver original
  1. import scipy as sp
  2. import scipy.linalg as linalg
  3.  
  4. class solution:
  5.     def __init__(self):
  6.         self.feed_flow = 70.0
  7.         self.feed = sp.array([0.15,0.25,0.4,0.2])
  8.         self.comp_names = ("xylene", "styrene", "toluene", "benzene")
  9.         self.var=("D_1", "B_1", "D_2", "B_2")
  10.         self.xylene = sp.array([0.07,0.18,0.15,0.24])
  11.         self.styrene = sp.array([0.04,0.24,0.1,0.65])
  12.         self.toluene = sp.array([0.54,0.42,0.54,0.1])
  13.         self.benzene = sp.array([0.35,0.16,0.21,0.01])
  14.         T0_comp_frac = self.feed_flow * self.feed    # component fraction on first tower (T0)
  15.         self.comp_eq = sp.array([self.xylene, self.styrene,
  16.                                  self.toluene, self.benzene]) #components linear equations
  17.         self.solve= sp.array(linalg.solve(self.comp_eq, T0_comp_frac))
  18.         self.D = self.solve[0] + self.solve[1]
  19.         self.B = self.solve[2] + self.solve[3]
  20.        
  21.     def comp(self):
  22.         print "D= %s" % self.D
  23.         print "B= %s" % self.B
  24.         for i in range(len(self.var)):
  25.                 print self.var[i], "=", self.solve[i]
  26.         flowname= ("D","B")
  27.         x = 0
  28.         while x<= 3:
  29.             y=0
  30.             z=0
  31.             while y<=2:
  32.                 temp = (self.comp_eq[x,y]*self.solve[y] +
  33.                         self.comp_eq[x,y+1]*self.solve[y+1])/(self.solve[y]+self.solve[y+1])
  34.                 y+=2
  35.                 print self.comp_names[x]+ " in "+ flowname[z]+" = ", temp
  36.                 z+=1
  37.             x+=1
  38.    
  39. class solution2(solution):
  40.     def __init__(self, percent):
  41.         self.feed_flow = 70.0 - 70.0 * percent
  42.         self.feed = sp.array([0.15,0.25,0.4,0.2])
  43.         self.comp_names = ("xylene", "styrene", "toluene", "benzene")
  44.         self.var=("D_1", "B_1", "D_2", "B_2")
  45.         self.xylene = sp.array([0.07,0.18,0.15,0.24])
  46.         self.styrene = sp.array([0.04,0.24,0.1,0.65])
  47.         self.toluene = sp.array([0.54,0.42,0.54,0.1])
  48.         self.benzene = sp.array([0.35,0.16,0.21,0.01])
  49.         T0_comp_frac = self.feed_flow * self.feed    # component fraction on first tower (T0)
  50.         self.comp_eq = sp.array([self.xylene, self.styrene,
  51.                                  self.toluene, self.benzene]) #components linear equations
  52.         self.solve= sp.array(linalg.solve(self.comp_eq, T0_comp_frac))
  53.         self.D = self.solve[0] + self.solve[1]
  54.         self.B = self.solve[2] + self.solve[3]
  55.    
  56.    
  57.        
  58. if __name__=="__main__":
  59.     solution=solution()
  60.     solution.comp()
  61.     print "*" * 80
  62.     percent = 0.01
  63.     solution2=solution2(0.01)
  64.     solution2.comp()


que estoy haciendo mal porque la segunda clase no hereda los parametros de la clase superior???
  #2 (permalink)  
Antiguo 07/08/2009, 12:54
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 8 meses
Puntos: 1360
Respuesta: problema con clases

El problema es que al redefinir __init__, estas redifiniendo el constructor y con ello los miembros en ella.

Lo ideal seria hacer lo siguiente
Código python:
Ver original
  1. import scipy as sp
  2. import scipy.linalg as linalg
  3.  
  4. class Solution:
  5.     def __init__(self):
  6.         self.feed_flow = 70.0
  7.         self.feed = sp.array([0.15,0.25,0.4,0.2])
  8.         self.comp_names = ("xylene", "styrene", "toluene", "benzene")
  9.         self.var=("D_1", "B_1", "D_2", "B_2")
  10.         self.xylene = sp.array([0.07,0.18,0.15,0.24])
  11.         self.styrene = sp.array([0.04,0.24,0.1,0.65])
  12.         self.toluene = sp.array([0.54,0.42,0.54,0.1])
  13.         self.benzene = sp.array([0.35,0.16,0.21,0.01])
  14.         T0_comp_frac = self.feed_flow * self.feed    # component fraction on first tower (T0)
  15.         self.comp_eq = sp.array([self.xylene, self.styrene,
  16.                                  self.toluene, self.benzene]) #components linear equations
  17.         self.solve= sp.array(linalg.solve(self.comp_eq, T0_comp_frac))
  18.         self.D = self.solve[0] + self.solve[1]
  19.         self.B = self.solve[2] + self.solve[3]
  20.        
  21.     def comp(self):
  22.         print "D= %s" % self.D
  23.         print "B= %s" % self.B
  24.         for i in range(len(self.var)):
  25.                 print self.var[i], "=", self.solve[i]
  26.         flowname= ("D","B")
  27.         x = 0
  28.         while x<= 3:
  29.             y=0
  30.             z=0
  31.             while y<=2:
  32.                 temp = (self.comp_eq[x,y]*self.solve[y] +
  33.                         self.comp_eq[x,y+1]*self.solve[y+1])/(self.solve[y]+self.solve[y+1])
  34.                 y+=2
  35.                 print self.comp_names[x]+ " in "+ flowname[z]+" = ", temp
  36.                 z+=1
  37.             x+=1
  38.    
  39. class Solution2(Solution):
  40.     def set_feed_flow(self, percent):
  41.         self.feed_flow = 70.0 - 70.0 * percent
  42.    
  43.        
  44. if __name__=="__main__":
  45.     solution=Solution()
  46.     solution.comp()
  47.     print "*" * 80
  48.     percent = 0.01
  49.     solution2=Solution2()
  50.     solution2.set_feed_flow(0.01)
  51.     solution2.comp()

Espero haberte ayudado
  #3 (permalink)  
Antiguo 07/08/2009, 13:15
AxL456
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema con clases

Hola...

antes que nada muchas gracias por tu respuesta tengo ya varias semanas estudiando python y hacerlo simplemente leyendo sin interactuar con otros pythonistas es en ocaciones algo dificil

Sobre lo que me comentas, ya lo habia intentado pero no me arroja el resultado esperado

El codigo que estoy escribiendo es un ejercicio de balance de masas en un tren de destilacion formado por 3 columnas, en esta pagina se explica a detalle:
http://www.engineeringwithpython.com...scription.html

en el codigo que te coloque en mi respuesta anterior (en donde reescribo el constructor __init__ para la segunda clase) yo logro que el valor feed_flow sea redefinido, y obtengo un resultado distinto para los valores de B y D al utilizar la segunda clase. Para ser mas especifico, lo que hago es que el valor feed_flow pase de 70.0 a 69.23 cambiando asi respectivamente los valores de B y D

este es el output de la ejecucion:
Código:
D= 43.75
B= 26.25
D_1 = 26.25
B_1 = 17.5
D_2 = 8.75
B_2 = 17.5
xylene in D =  0.114
xylene in B =  0.21
styrene in D =  0.12
styrene in B =  0.466666666667
toluene in D =  0.492
toluene in B =  0.246666666667
benzene in D =  0.274
benzene in B =  0.0766666666667
********************************************************************************
D= 43.3125
B= 25.9875
D_1 = 25.9875
B_1 = 17.325
D_2 = 8.6625
B_2 = 17.325
xylene in D =  0.114
xylene in B =  0.21
styrene in D =  0.12
styrene in B =  0.466666666667
toluene in D =  0.492
toluene in B =  0.246666666667
benzene in D =  0.274
benzene in B =  0.0766666666667
si te das cuenta lo que te coloco en negrita ha cambiado al ejecutar la segunda clase..

si realizo el cambio que tu me indicas, este es el output:
Código:
D= 43.75
B= 26.25
D_1 = 26.25
B_1 = 17.5
D_2 = 8.75
B_2 = 17.5
xylene in D =  0.114
xylene in B =  0.21
styrene in D =  0.12
styrene in B =  0.466666666667
toluene in D =  0.492
toluene in B =  0.246666666667
benzene in D =  0.274
benzene in B =  0.0766666666667
********************************************************************************
D= 43.75
B= 26.25
D_1 = 26.25
B_1 = 17.5
D_2 = 8.75
B_2 = 17.5
xylene in D =  0.114
xylene in B =  0.21
styrene in D =  0.12
styrene in B =  0.466666666667
toluene in D =  0.492
toluene in B =  0.246666666667
benzene in D =  0.274
benzene in B =  0.0766666666667
como te puedes dar cuenta los valores en negrita no cambian al ejecutar la segunda clase, por lo que el valor feed_flow no esta siendo redefinido adecuadamente..

no entiendo muy bien el problema porque todavia no domino bien las clases, pero lo que veo es que al ejecutar estas lineas:
Código:
solution2.set_feed_flow(0.01)
solution2.comp()
cuando python ejecuta la linea solution2.comp() se olvida del "reset" al valor feed_flow creado por la linea solution2.set_feed_flow(0.01). lo que creo que esta sucediendo es que el contructor __init__ de la clase principal, siempre es ejecutado reescribiendo cualquier valor que haya sido modificado posteriormente..


que me sugieres? muevo los parametros fuera del constructor __init__??


***Edit***

Despues de hacer varias pruebas y buscar algo de documentacion sobre clases en la red me di cuenta que lo que trato de hacer es mas facilmente logrado usando def en vez de clases..

esto tiene que ver con algo llamado "tiempo de ejecucion" y "tiempo de invocacion" (en ingles "execution time" y "calling time" no se si es tecnicamente correcta mi traduccion)

por lo que he leido, las clases son creadas en "tiempo de ejecucion". Al ser leidas se les asigna un "namespace" por lo que cada variable dentro de ella es asignada a un valor al ser ejecutado el programa y cuando trato de cambiar la variable feed_flow en lineas posteriores me encuentro que las variables que dependían de feed_flow ya tienen un valor asociado.

esto no pasa con los def ya que a los def se les asigna un "namespace" cada vez que son "llamados" y si alguna variable dentro de dicho def es cambiada posteriormente, las variables asociadas tambien cambiarian..

se que es un poco enredado (y mas aun con la explicacion tan miserable que estoy dando xD) por lo que coloco el codigo para que puedan verlo y entenderlo mejor:
Código Python:
Ver original
  1. import scipy as sp
  2. import scipy.linalg as linalg
  3.  
  4. def feedflow(feedflow):
  5.     feed_flow = feedflow
  6.     feed = sp.array([0.15,0.25,0.4,0.2])
  7.     xylene = sp.array([0.07,0.18,0.15,0.24])
  8.     styrene = sp.array([0.04,0.24,0.1,0.65])
  9.     toluene = sp.array([0.54,0.42,0.54,0.1])
  10.     benzene = sp.array([0.35,0.16,0.21,0.01])
  11.     comp_names = ("xylene", "styrene", "toluene", "benzene")
  12.     var=("D_1", "B_1", "D_2", "B_2")
  13.     T0_comp_frac = feed_flow * feed
  14.     comp_eq = sp.array([xylene, styrene, toluene, benzene])
  15.     solve= sp.array(linalg.solve(comp_eq, T0_comp_frac))
  16.     D = solve[0] + solve[1]
  17.     B = solve[2] + solve[3]
  18.     variables={"feed_flow":feed_flow,"feed":feed, "xylene": xylene,
  19.                "styrene":styrene,"toluene":toluene,"benzene":benzene,
  20.                "comp_names":comp_names, "var":var,"T0_comp_frac":T0_comp_frac,
  21.                "comp_eq":comp_eq, "solve":solve, "D":D, "B":B}
  22.     return variables
  23.  
  24. def comp():
  25.     print "D= %s" % variables["D"]
  26.     print "B= %s" % variables["B"]
  27.     for i in range(len(var)):
  28.         print variables["var"][i], "=", variables["solve"][i]
  29.     flowname= ("D","B")
  30.     x = 0
  31.     while x<= 3:
  32.         y=0
  33.         z=0
  34.         while y<=2:
  35.             temp = ((variables["comp_eq"][x,y]*variables["solve"][y] +
  36.                     variables["comp_eq"][x,y+1]*variables["solve"][y+1])/
  37.                     (variables["solve"][y]+variables["solve"][y+1]))
  38.             print variables["comp_names"][x]+ " in "+ flowname[z]+" = ", temp
  39.             y+=2
  40.             z+=1
  41.         x+=1
  42.        
  43. if __name__=="__main__":
  44.     variables=feedflow(70)
  45.     comp()
  46.     print "*" * 80
  47.     variables=feedflow(60)
  48.     comp()

lo interesante es que esto se puede lograr usando def's anidados dentro de luna clase, pero de tomaría escribir mas lineas de código..

Última edición por AxL456; 07/08/2009 a las 16:05 Razón: consegui el problema
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:18.