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.
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__
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
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: