python orientacion objetos polinux

29
Python 010 Seminarios de Formación Polinux València 08/05/2008 Andrés Ignacio Martínez Soto [email protected] http://www.andresmartinezsoto.net

Upload: julian-andres-gil-santos

Post on 23-Jul-2015

65 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Python Orientacion Objetos Polinux

Python 010

Seminarios de Formación Polinux

València 08/05/2008

Andrés Ignacio Martínez [email protected]://www.andresmartinezsoto.net

Page 2: Python Orientacion Objetos Polinux

Python 010

Page 3: Python Orientacion Objetos Polinux

Python 010

Contenido del seminario: Python orientado a objetos

Clases Métodos

Polimorfismo Encapsulación

Sobrecarga de operadores Herencia simple y múltiple Errores y excepciones

Page 4: Python Orientacion Objetos Polinux

Python 010

Python orientado a objetos

Page 5: Python Orientacion Objetos Polinux

Python 010

Clases y métodos

Page 6: Python Orientacion Objetos Polinux

Python 010

Clases Ejemplo mínimo:

Ejemplo mínimo funcional:

class MiClase:pass

class Complejo:

def __init__ (self,real, imaginaria): self.r = real self.i = imaginaria print ”Complejo con real=%f e imaginaria=%f” % (self.r, self.i)

def MostrarComplejo (self): print ”%f + %f i ” % (self.r,self.i)

def __del__ (self): print "Destruido el complejo”

Page 7: Python Orientacion Objetos Polinux

Python 010

Clases desglosadas: Definición:

Constructor:

Destructor:

Métodos:

class Impresora:detalles_de_la_clase

def __init__ (self,*args,**kwargs):detalles_del_constructor

def __del__ (self,*args,**kwargs):detalles_del_destructor

def metodo (self,*args,**kwargs):detalles_del_método

*args es un vector de argumentos variable (al estilo de argv de C/C++)Imprimir(”Hola Mundo”,3)

**kwargs es una lista de argumentos del estilo:

Imprimir(cadena=”Hola”,veces=2)

Page 8: Python Orientacion Objetos Polinux

Python 010

Clases desglosadas: Instanciación:

>>> c = Complejo(1,2)Complejo con real=1.000000 e imaginaria=2.000000>>> c.MostrarComplejo() 1.000000 + 2.000000 i >>> Destruido el complejo

Page 9: Python Orientacion Objetos Polinux

Python 010

Clases desglosadas: Variables de ámbito 'global' a la clase:

Variables de ámbito local a un método:

class Complejo:real = 0imaginaria = 0

def __init__ (self, real, imaginaria):self.real=realself.imaginaria=imaginaria

def mi_metodo (self):variable=”Cadenita”

entero=100

Page 10: Python Orientacion Objetos Polinux

¡Ojo!Es muy importante el

parámetro selfpuesto que indica que el

métodopertenece a la propia clase

(el *this de C++)

Python 010

Métodos: Métodos con argumentos fijos:

Métodos con argumentos variables:

def SoltarAgua (self,cantidad):self.agua-=cantidadreturn

def MostrarArgumentos (self,*args,*kwargs):for i len(args):

print args[i];for j in len(kwargs):

print kwargs[j];return

Page 11: Python Orientacion Objetos Polinux

Python 010

Polimorfismo de métodosSi en una clase de Python definimos varios métodos con el mismo nombre (al estilo de otros lenguajes como C++) con la intención de llamar a un método según el número y nombre de argumentos; éste llamaría al último método definido con ese nombre (es decir, el último implementado (hacia bajo) ).

class Foo:def __init__(self):

print "SoyFoo"

def Bar(self):print "Bar"

def Bar(self,param1,param2):print "Bar",param1,param2

def __del__(self):print "Ha muerto foo"

Ejemplo>>> a = Foo()SoyFoo>>> a.Bar()Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: Bar() takes exactly 3 arguments (1 given)>>> a.Bar("a","a")Bar a a>>> Ha muerto foo

Page 12: Python Orientacion Objetos Polinux

Python 010

Polimorfismo de métodosSi lo que queremos hacer es simular el comportamiento de C++ o de otros lenguajes de programación, deberemos utilizar 'tuplas' de argumentos con la intención de que el método discierna entre una acción u otra:

Nota: Si colocamos un * (asterisco) delante de una variable pasada como argumentos, Python la interpreta como una tupla.

def Bar(self,*argumentos):if (len(argumentos)==1):

print "Bar"

elif (len(argumentos)==2):print "Bar",argumentos[0],argumentos[1]

>>> Bar(1)Bar>>> Bar(1,4)Bar 1 4

Page 13: Python Orientacion Objetos Polinux

Python 010

EncapsulaciónEn C++ y parecidos, para ”ocultar” un método o atributo a otras clases derivadas o a instancias de la clase, utilizamos modificadores como {public,private,protected ... } ;en Python se utiliza algo más sencillo:

__MiAtributoPrivado → atributo privado def __MétodoPrivado (self,parámetros): → método privado

Si comienza con dos ”__” (guiones bajos) es privado a la propia clase.

class Ejemplo: def publico(self): print "Publico" def __privado(self): print "Privado"

>>> ej = Ejemplo()>>> ej.publico()Publico>>> ej.__privado()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: Ejemplo instance has no attribute '__privado'>>>

Page 14: Python Orientacion Objetos Polinux

Python 010

Sobrecarga de operadores

Page 15: Python Orientacion Objetos Polinux

Python 010

Sobrecarga de operadores: Modificaremos éste método:

Por este otro:

def Imprimir (self): if (self.NivelTinta()==True): print self.text

def __str__ (self): if (self.NivelTinta()==True):

return self.text

Los métodos que comienzan por __nombremetodo__ son métodos especiales, en este caso __str__ es un metódo que devuelve una

cadena, para que pueda ser imprimida.

Page 16: Python Orientacion Objetos Polinux

Python 010

Más sobre la sobrecarga de operadores:

Operador Sobrecarga Cabecera métodononzero (true o false) __nonzero__ def __nonzero__(self):== (comparación) __cmp__ def __cmp__(self,otro):= (asignación) __eq__ def __eq__ (self,otro):!= (comparación) __ne__ def __ne__(self,otro):< / <= (comparación) __lt__ / __le__ def __lt__(self,otro):> / >= (comparación) __gt__/__ge__ def __gt__(self,otro): + / - (suma,resta) __add__ / __sub__ def __add_(self,otro): * / '/' (multiplicación,división) __mul__ / __div__ def __mul__ (self,otro):<< (desplazamiento) __lshift__ def __lshift__(self, otro):>> (desplazamiento) __rshift__ def __rshift__(self, otro)AND (AND lógico) __and__ def __and__(self,otro):OR (OR lógico) __or__ def __or__(self, otro)XOR (XOR lógico) __xor__ def __xor__(self,otro):len (longitud de elemento) __len__ def __len__ (self,otro):invert (invertir) __invert__ def __invert__(self):call (llamada a objetos/métodos) __call__ def __call__(self,[args]):[ ] (acceso lectura elemento) __getitem__ def __getitem__(self, key):[ ] (acceso escritura elemento) __settitem__ def __setitem__(self, key, item):del a[b] (borrado objeto) __delitem__ def __delitem__(self, clave):

Page 17: Python Orientacion Objetos Polinux

Python 010 Un ejemplo completo (sin herencia):

class ImpresoraMejorada: def __init__ (self, cadena): self.text = cadena; self.tinta = 100; self.long = self.CalcularLenCadena();

def Imprimir (self): if (self.NivelTinta()==True): for i in range(len(self.text)): print self.text[i]; self.tinta-=5;

def CalcularLenCadena(self): return ( len(self.text) )

def NivelTinta(self): if (self.tinta==100): print "Tinta llena"; return True; elif (self.tinta<100 and self.tinta>75): print "Nivel medio"; return True; elif (self.tinta<75 and self.tinta>35): print "Nivel medio_bajo"; return True; else: print "Dame tinta, por favor"; return False;

def Apagar(self): self.__del__() def __del__ (self): print "Desconectando la impresora"

Page 18: Python Orientacion Objetos Polinux

Python 010

Herencia

class Base:...

class Derivada (Base):Base.__init__(self, args):

.......

Entre paréntesis el nombre de la clase base.

Page 19: Python Orientacion Objetos Polinux

Python 010

Herencia, ejemplo → vehículos

Page 20: Python Orientacion Objetos Polinux

Python 010 Herencia ejemplo → Clase Vehículo (1/2)

class Vehiculo: """Abstracción de vehículo""" def __init__ (self,gasolina): """Constructor""" self.gasolina = gasolina self.bateria=100 print "Fabricado nuevo vehículo con %d litros de gasolina"%(self.gasolina) def Arrancar(self): """Arrancar un vehículo""" if self.gasolina > 0: print "Booting up the vehicle..." print "Rrrrrr... motor al ralentí" self.bateria-=35 self.gasolina-=25 elif (self.bateria<35) or (self.gasolina<10): print "Trata de arrancarlo...trata de arrancarlo"

Documentar tu código con los __docstrings__ es importante

para que los demás entendamos el código

Page 21: Python Orientacion Objetos Polinux

Python 010

Herencia, ejemplo → Clase Vehículo (2/2)

def Conducir(self): """Conducir""" if self.gasolina > 0: self.gasolina-=5 print "Quedan", self.gasolina, "litros" else: print "Llama a la grúa que nos hemos quedado sin gasofa…"

def __del__(self): """Destructor""" print "Jooo, ¿por qué me desguazas?" print "Vehículo desguazado"

Page 22: Python Orientacion Objetos Polinux

Python 010

Herencia, ejemplo → Clase Coche

class Coche (Vehiculo): """Coche""" def __init__(self,modelo,conductor,gasolina): """Constructor""" Vehiculo.__init__(self,gasolina) self.modelo=modelo self.conductor=conductor print "Bienvenido ",self.conductor," al ",self.modelo def Vacilar(self): """Método para vacilar a los demás conductores...""" print "Imbécil, ¡mira por dónde vas!" def Adelantar(self,Autobus): """Método para adelantar a otros vehículos""" print "Pisando el acelerador... " print "Hemos adelantado un autobús que iba hacia",Autobus.destino

Page 23: Python Orientacion Objetos Polinux

Python 010

Herencia, ejemplo → Clase Autobúsclass Autobus (Vehiculo): """Autobús""" def __init__(self,plazas,conductor,destino,gasolina): """Constructor""" Vehiculo.__init__(self,gasolina) self.plazas=plazas; self.conductor=conductor ;self.destino=destino print "Bienvenido al autobús destino %s"%(self.destino) def Subir(self,NumPersonas): """Recoger personas""" if (self.plazas<NumPersonas): print "Lo siento, no hay plazas"; else: self.plazas-=NumPersonas def Bajar(self,NumPersonas): """Dejar personas""" self.plazas+=NumPersonas; print "Han bajado %d personas"%(NumPersonas);

Page 24: Python Orientacion Objetos Polinux

Python 010

Herencia, ejemplo → Prueba de fuego...>>> from vehicles import *>>> c=Coche("Fantástico","Maikel Nai",100)Fabricado nuevo vehículo con 100 litros de gasolinaBienvenido Maikel Nai al Fantástico>>> a=Autobus(100,"Paquito","A Saber",100)Fabricado nuevo vehículo con 100 litros de gasolinaBienvenido al autobús destino A Saber>>> a.Arrancar()Booting up the vehicle...Rrrrrr... motor al ralentí>>> c.Arrancar()Booting up the vehicle...Rrrrrr... motor al ralentí>>>

>>> c.Vacilar()Imbécil, ¡mira por dónde vas!>>> c.Adelantar(a)Pisando el acelerador... Hemos adelantado un autobús que

iba hacia A Saber>>> c.Conducir()Quedan 70 litros>>> a.Conducir()Quedan 70 litros>>>

>>> Jooo, ¿por qué me desguazas?Vehículo desguazadoJooo, ¿por qué me desguazas?Vehículo desguazado

Page 25: Python Orientacion Objetos Polinux

Python 010

Herencia múltipleEntre paréntesis los nombres de

las clases base.

class Base1:...

class Base2...

class Derivada (Base1,Base2):Base1.__init__(self, args);Base2.__init__(self, args):

.......

Page 26: Python Orientacion Objetos Polinux

Python 010 Herencia múltiple → ejemplo

Page 27: Python Orientacion Objetos Polinux

Python 010

Errores y excepcionesComo todo lenguaje moderno, Python dispone de excepciones que es un mecanismo para tratar los ”errores” dentro del flujo de ejecución normal de un programa.

Al producirse un ”error”, el intérprete de Python se 'queja' del error, y termina la ejecución del programa. Si existiese una excepción definida para manejar dicho ”error”, entonces saltaría a la excepción, y ésta 'trataría de solucionar el error'.

>>> def division(a, b):... return a / b... >>> def calcular():... division(27, 0)... >>> calcular()Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in calcular File "<stdin>", line 2, in divisionZeroDivisionError: integer division or modulo by zero>>>

Page 28: Python Orientacion Objetos Polinux

Python 010

Errores y excepcionesAl producirse una excepción, el intérprete de Python lanza un ”traceback” que muestra las llamadas que provocaron la excepción (la pila de llamadas del programa).

En el ejemplo anterior, el error fue causado por la llamada a calcular que a su vez llama a división(27,0), y al final, ejecuta (return a/b) que es la línea que provoca la excepción.

En Python se utiliza una construcción:

def division(a,b):try:

return (a/b) except ZeroDivisionError:

print ”¡Qué no se puede dividir por zero!”

>>> division(1.0,3)0.33333333333333331>>> division(1.0,0)¡Qué no se puede dividir por zero!>>>

Page 29: Python Orientacion Objetos Polinux

Python 010

Errores y excepciones

Try → Poner aquí lo que puede causar un error/excepción.Except → Poner aquí como tratar el error/excepción.Finally → Se ejecuta siempre se produzca o no un error, sirve para 'limpiar' o reiniciar las variables que produjeron un error (por ejemplo, hacer un rollback e impedir el cambio de un registro)...

Podemos definir nuestras propias excepciones, bastará con que hereden de ”Exception”....

class MiError(Exception): def __init__(self, valor): self.valor = valor def __str__(self): return "Error " + str(self.valor)try: if resultado > 20: raise MiError(33)except MiError, e: print e

Raise lanza una excepción o un objeto ”MiError”

que es una excepción