Revista Tecnología

Guia Python: herencia y método especial.

Publicado el 04 agosto 2013 por Hugo Rep @HugoRep

python logo
Python es un lenguaje de script desarrollado por Guido van Rossum.
Podemos codificar empleando programación lineal, estructurada y orientada a objetos (tengamos en cuenta que esta última es la que se ha impuesto en la actualidad).

Se cuenta con intérpretes de Python en múltiples plataformas: Windows, Linux, Mac etc. Se pueden desarrollar aplicaciones de escritorio como aplicaciones web. Empresas como Google, Yahoo, Nasa etc. utilizan este lenguaje para sus desarrollos (actualmente el creador de Python Guido van Rossum trabaja para Google.)

Se puede ejecutar instrucciones de Python desde la línea de comando o creando archivos con extensión *.py. Cuando uno comienza a aprender este lenguaje la línea de comandos nos provee una retroalimentación del resultado en forma inmediata.

El objetivo de este tutorial es presentar en forma progresiva los conceptos fundamentales de este lenguaje y poder analizar los problemas resueltos y codificar los problemas propuestos en este mismo sitio, sin tener que instalar en un principio el Python en su equipo (o luego de instalado poder avanzar con el tutorial en cualquier máquina conectada a internet).

Herencia.

python Estructura condicional if-elif.

Otra característica que tiene que tener un lenguaje para considerarse orientado a objetos es la HERENCIA.

La herencia significa que se pueden crear nuevas clases partiendo de clases existentes, que tendrá todas los atributos y los métodos de su 'superclase' o 'clase padre' y además se le podrán añadir otros atributos y métodos propios.

En Python, a diferencia de otros lenguajes orientados a objetos (Java, C#), una clase puede derivar de varias clases, es decir, Python permite la herencia múltiple.

Superclase o clase padre.

Clase de la que desciende o deriva una clase. Las clases hijas (descendientes) heredan (incorporan) automáticamente los atributos y métodos de la la clase padre.

Subclase.

Clase desciendiente de otra. Hereda automáticamente los atributos y métodos de su superclase. Es una especialización de otra clase. Admiten la definición de nuevos atributos y métodos para aumentar la especialización de la clase.

Veamos algunos ejemplos teóricos de herencia:

1) Imaginemos la clase Vehículo. Qué clases podrían derivar de ella

Vehiculo

   Colectivo   Moto   Auto
  
   FordK   Renault 9

Siempre hacia abajo en la jerarquía hay una especialización (las subclases añaden nuevos atributos y métodos)

2) Imaginemos la clase Software. Qué clases podrían derivar de ella?

Software

   DeAplicacion   DeBase

ProcesadorTexto   PlanillaDeCalculo   SistemaOperativo

Word   WordPerfect   Excel   Lotus123   Linux   Windows
  

Si vemos que dos clase responden a la pregunta ClaseA "..es un.." ClaseB es posible que haya una relación de herencia.
Por ejemplo:
Auto "es un" Vehiculo
Circulo "es una" Figura
Mouse "es un" DispositivoEntrada
Suma "es una" Operacion

Ahora plantearemos el primer problema utilizando herencia en Python. Supongamos que necesitamos implementar dos clases que llamaremos Suma y Resta. Cada clase tiene como atributo valor1, valor2 y resultado. Los métodos a definir son cargar1 (que inicializa el atributo valor1), carga2 (que inicializa el atributo valor2), operar (que en el caso de la clase "Suma" suma los dos atributos y en el caso de la clase "Resta" hace la diferencia entre valor1 y valor2, y otro método mostrarresultado.
Si analizamos ambas clases encontramos que muchos atributos y métodos son idénticos. En estos casos es bueno definir una clase padre que agrupe dichos atributos y responsabilidades comunes.

La relación de herencia que podemos disponer para este problema es:

Operacion

   Suma   Resta

Solamente el método operar es distinto para las clases Suma y Resta (esto hace que no lo podamos disponer en la clase Operacion), luego los métodos cargar1, cargar2 y mostrarresultado son idénticos a las dos clases, esto hace que podamos disponerlos en la clase Operacion. Lo mismo los atributos valor1, valor2 y resultado se definirán en la clase padre Operacion.

En Pyton la codificación de estas tres clases es la siguiente:

class Operacion:
   def cargar1(self,v1):
   self.valor1=v1
   def cargar2(self,v2):
   self.valor2=v2
   def imprimir(self):
   print self.resultado
   print '<br>'


class Suma(Operacion):
   def operar(self):
   self.resultado=self.valor1+self.valor2


class Resta(Operacion):
   def operar(self):
   self.resultado=self.valor1-self.valor2


s=Suma()
s.cargar1(10)
s.cargar2(20)
s.operar()
print 'La suma es:'
s.imprimir()
r=Resta()
r.cargar1(10)
r.cargar2(2)
r.operar()
print 'La resta es:'
r.imprimir()

Veamos como es la sintaxis para indicar que una clase hereda de otra:

class Suma(Operacion):

Indicamos entre paréntesis el nombre de la clase padre (con esto estamos indicando que todos los métodos y atributos de la clase Operación son también métodos de la clase Suma.

Luego la característica que añade la clase Suma es el siguiente método:

def operar(self):
   self.resultado=self.valor1+self.valor2

El método operar puede acceder a los atributos heredados.

Ahora podemos decir que la clase Suma tiene cuatro métodos (tres heredados y uno propio) y 3 atributos

Si creamos un objeto de la clase Suma tenemos:

s=Suma()
s.cargar1(10)
s.cargar2(20)
s.operar()
print 'La suma es:'
s.imprimir()

Podemos llamar tanto al método propio de la clase Suma "operar()" como a los métodos heredados. Quien utilice la clase Suma solo debe conocer que métodos tiene (independientemente que pertenezcan a la clase Suma o a una clase superior)

La lógica es similar para declarar la clase Resta:

class Resta(Operacion):
   def operar(self):
   self.resultado=self.valor1-self.valor2

y la definición de un objeto de dicha clase:

r=Resta()
r.cargar1(10)
r.cargar2(2)
r.operar()
print 'La resta es:'
r.imprimir()

La clase Operación agrupa en este caso un conjunto de atributos y métodos comunes a un conjunto de subclases (Suma, Resta). No tiene sentido definir objetos de la clase Operacion.

El planteo de jerarquías de clases es una tarea compleja que requiere un perfecto entendimiento de todas las clases que intervienen en un problema, cuales son sus atributos y responsabilidades.

Método especial __str__

python Estructura de datos tipo tupla.

Podemos hacer que se ejecute un método definido por nosotros cuando pasamos un objeto a la función print o cuando llamamos a la función str.

Que sucede cuando llamamos a la función print y le pasamos como parámetro un objeto?

class Persona:
   def __init__(self,nom,ape):
   self.nombre=nom
   self.apellido=ape

per=Persona('Jose','Rodriguez')
print per

Nos muestra algo parecido a esto:

<__main__.Persona instance at 0xf9e0a60ec5872050>

Python nos permite redefinir el método que se debe ejecutar. Esto se hace definiendo en la clase el método especial __str__

En el ejemplo anterior si queremos que se muestre el nombre y apellido separados por coma cuando llamemos a la función print el código que debemos implementar es el siguiente:

class Persona:
   def __init__(self,nom,ape):
   self.nombre=nom
   self.apellido=ape
   def __str__(self):
   cadena=self.nombre+','+self.apellido
   return cadena

per=Persona('Jose','Rodriguez')
print per

Como vemos debemos implementar el método __str__ y retornar un string, este luego será el que imprime la función print:

def __str__(self):
   cadena=self.nombre+','+self.apellido
   return cadena

Esta característica definida en Python nos permite crear programas muy legibles y flexibles.

El método __str__ también se ejecuta si llamamos a la función str y pasamos como parámetro un objeto que tiene definido dicho método:

class Persona:
   def __init__(self,nom,ape):
   self.nombre=nom
   self.apellido=ape
   def __str__(self):
   cadena=self.nombre+','+self.apellido
   return cadena

per1=Persona('Jose','Rodriguez')
per2=Persona('Ana','Martinez')
print str(per1)+'-'+str(per2)  # Jose,Rodriguez-Ana,Martinez

python Estructura de datos tipo diccionario

Si te ha gustado el artículo inscribete al feed clicando en la imagen más abajo para tenerte siempre actualizado sobre los nuevos contenidos del blog:

Guia Python: herencia y método especial.


Volver a la Portada de Logo Paperblog