Google+ Seguidores

lunes, 27 de octubre de 2014

Clases y objetos en python (Programacion Orientada a Objetos)

    6

Programación Orientada a Objetos
Programación Orientada a Objetos
Python es un lenguaje de programación orientada a objetos (POO). La programación orientada a objetos tiene sus raíces en la década del 60, pero es en los 80 que se convierte en el principal paradigma de la programación de un nuevo software.

Hasta ahora los ejercicios y ejemplos que he utilizado han sido utilizando la programación funcional (realizando funciones que den solución a los problemas). En la programación orientada a objetos la atención se centra en la creación de objetos que contienen los datos y funcionalidad juntos.

Edito: Aquí puedes encontrar ejercicios para practicar este paradigma: Ejercicios de Clases y Objetos en python (Parte 1)

Definiciones necesarias:

¿Qué es un Objeto?
Los objetos son la clave para entender la Programación Orientada a Objetos. Si miramos a nuestro alrededor  encontraremos un sin fin de objetos de la vida real: perro, escritorio, televisor, bicicleta, etc...

¿Qué es un Atributo?
Los atributos o propiedades de los objetos son las características que puede tener un objeto: Si el objeto fuera Perro, los atributos podrían ser: tamaño, edad, color, raza, etc...

¿Qué es un Método?
Los métodos son la acción o función que realiza un objeto. Si nuestro objeto es Perro, los métodos pueden ser: caminar, ladrar, saltar, dormir, etc...

¿Qué es una Clase?
Con todos los conceptos anteriores explicados, se puede decir que una clase es una plantilla genérica de un objeto. La clase proporciona variables iniciales de estado (donde se guardan los atributos) e implementaciones de comportamiento (métodos)

¿Qué es una Instancia?
Ya sabemos que una clase es una estructura general del objeto. Por ejemplo, podemos decir que la clase Mascota necesita tener un nombre y una especie, pero no nos va a decir cual es el nombre y cual es la especie, es aquí donde entran las instancias. Una instancia es una copia específica de la clase con todo su contenido.
Ejemplo: Mateo = Mascota ("Mateo", "Gato")
Aquí podemos decir que Mateo es una instancia de la clase Mascota.

Clases y Objetos en python
Estructura de una Clase

Las clases nos dan la posibilidad de crear estructuras de datos más complejas. En nuestro ejemplo crearemos una clase Mascotas que realizará un seguimiento del nombre y la especie (que pasaremos como atributos).

Ejemplo de clases y objetos en python:

Definiendo clase Mascota en Python
Definiendo clase Mascota en Python

Como definir una clase en Python

Linea 5

class Mascota(object):

Aquí es donde empezamos a crear nuestra clase (lo hacemos con la palabra class). La segunda palabra (Mascota) es el nombre que le daremos a nuestra clase. La tercera palabra que se encuentra dentro de los paréntesis (object) se conoce con el nombre de herencia (mas tarde hablaré sobre el concepto de herencia). Lo que debemos saber es que "object" es una variable especial en python que se utiliza de herencia cuando creamos una nueva clase en python.

Lineas 7-9

def __init__(self, nombre, especie):
----self.nombre = nombre
----self.especie = especie

Cuando creamos una nueva mascota, necesitamos inicializarla con un nombre y una especie. El método __init__ (método especial para las funciones que forman parte de una clase) es una función especial en python que inicializa la clase con los atributos que nosotros le pasemos. Por ejemplo: si corremos el código Teo = Mascota("Teo", "Perro") , el método __init__ es llamado con los valores Teo, "Teo" y "Perro" en las variables self, nombre y especies, respectivamente.

La variable self es una instancia de la clase y es bueno aclarar que no es una palabra reservada de python, cualquier etiqueta utilizada como primer parámetro tendría el mismo valor (se desaconseja el uso de otras etiquetas por un tema de convención). O sea que, cada vez que declaremos un método en python, vamos a tener que agregarle la variable self para que cuando sea invocado el método, Python pase el objeto instanciado y opere con los valores actuales de esa instancia.
También en estas líneas almacenamos el atributo nombre en el parámetro nombre (self.nombre = nombre) y también (self.especie = especie).

Lineas 11-15

def darNombre(self):
----return self.nombre

def darEspecie(self):
----return self.especie

Podemos definir métodos que necesitemos para mostrar e interactuar con los contenidos de las instancias. El método darNombre toma una instancia de la clase Mascota y nos devuelve el nombre de la misma. Lo mismo pasa con el método darEspecie. Una ves mas necesitamos el parámetro self para que la función sepa con que instancia de Mascota trabajar y así poder averiguar su contenido.

Lineas 17-18

def __str__(self):
----return "%s es un %s" % (self.nombre, self.especie)

El método __str__ es una función especial de python (nos podemos dar cuenta de que los métodos especiales de python comienzan y terminan con un doble guión bajo).
Este método nos proporciona una cadena (informal) de la representación del objeto. En nuestro caso, si definimos la instancia Teo = Mascota("Teo", "Perro"), el método __str__ nos va a devolver la cadena: Teo es un Perro.

Interactuando con nuestra primera clase Mascota

Ahora vamos a ver como podemos interactuar en consola con la clase Mascota que hemos creado. Para hacer esto debemos abrir la consola y pararnos en el directorio donde tenemos guardado nuestro archivo Mascotas.py. Una ves ahí escribimos "python" para abrir el shell interactivo de python.

Interactuando con la clase Mascota en python
Interactuando con la clase Mascota

Lo primero que hacemos es importar la clase Mascota del archivo Mascotas.py
>>>from Mascotas import Mascota

Luego creamos una instancia de la clase Mascota y la llamamos tito
>>>tito = Mascota("Tito", "Perro")

Después devolvemos la cadena "Tito es un Perro" de dos maneras diferentes: la primera con el nombre de la instancia + el método:
>>>print "Tito es un %s" % tito.darEspecie()
La segunda: llamamos la clase + el método y le pasamos entre paréntesis la instancia (tito)
>>>print "Tito es un %s" % Mascota.darEspecie(tito)

El último print nos arroja un error porque necesitamos pasar la instancia (tito).

Otros ejemplos de la clase Mascota

Para probar seguimos utilizando la consola de python y el archivo llamado Mascotas.py donde se encuentra nuestra clase Mascota:

Ejemplo 1
>>>from Mascotas import Mascota
>>>rocco = Mascota("Rocco", "Perro")
>>>rocco.darNombre()
"Rocco"
>>>rocco.darEspecie()
"Perro"
>>>print rocco
Rocco es un Perro

Ejemplo 2
>>>from Mascotas import Mascota
>>>tito = Mascota("Tito", "Gato")
>>>tito.darNombre()
"Tito"
>>>tito.darEspecie()
"Gato"
>>>print tito
Tito es un Gato

Ejemplo 3
>>>from Mascotas import Mascota
>>>pepe = Mascota("Pepe", "Pato")
>>>pepe.darNombre()
"Pepe"
>>>pepe.darEspecie()
"Pato"
>>>print pepe
"Pepe es un Pato"

Crear subclases de la clase Mascota (herencia)

A veces no nos alcanza definiendo solo una clase como Mascota. Por ejemplo, algunas mascotas pueden ser perros y a la mayoría de ellos les gusta perseguir gatos, y tal ves nosotros queramos saber a que perro le gusta perseguir los gatos y a que perro no. Podemos hacer otra clase Perro que va a heredar la clase Mascota, esto no solo nos dará la estructura de la clase Mascota, si no que también podremos agregar una estructura específica para la clase Perro.

Herencia Clase Perro en python
Clase Perro en python
Clase Perro:
Definimos la clase con la palabra class seguido del nombre de la clase (en nuestro caso Perro) y luego entre paréntesis colocamos la clase que queremos heredar (en nuestro caso es la clase Mascota).
Queremos especificar que toda la clase perro va a tener como especie "Perro" y también si al perro le gusta perseguir a los gatos. Para ello debemos escribir la función de inicialización propia. También tenemos que llamar a la función de inicialización de la clase padre porque queremos que el nombre y la especie se inicialicen.

Podemos definir una subclase igual para los gastos:

Herencia Clase Gato en python
Clase Gato en python

Examinando diferencias entre Perro y Mascota:

>>>from Mascotas import Mascota, Perro
>>>mascota = Mascota("Falucho", "Perro")
>>>perro = Perro("Falucho", True)

La función que se utilizará a continuación (isinstance), es una función especial que chequea si una instancia es de un determinado tipo de clase. Podemos ver que mascota es una instancia de Mascota, y perro es una instancia de las dos clases (Mascota, Perro).

>>>isinstance(mascota, Mascota)
True
>>>isinstance(mascota, Perro)
False
>>>isinstance(perro, Mascota)
True
>>>isinstance(perro, Perro)
True

Esto se da porque mascota es una Mascota, pero no un Perro, no podemos llamar la función persigueGatos porque la clase Mascota no tiene este método. Pero si podemos llamar el método persigueGatos en perro porque se define para la clase Perro. Si podemos llamar el método darNombre  en mascota y perro porque los dos son una instancia de Mascota aunque darNombre no esté definido explícitamente en la clase Perro (hereda de Mascota sus métodos).

Perros y Gatos

Crearemos algunos gatos y perros:

>>> from Mascotas import Gato, Perro
>>> pluto = Perro("Pluto", True)
>>> snoopy = Perro("Snoopy", False)
>>> tom = Gato("Tom", True)
>>> felix = Gato("Felix", False)
>>> print pluto
Pluto es un Perro
>>> print snoopy
Snoopy es un Perro
>>> print tom
Tom es un Gato
>>> print felix
Felix es un Gato
>>> print "%s persigue gatos: %s" % (pluto.darNombre(), pluto.persigueGatos())
Pluto persigue gatos: True
>>> print "%s persigue gatos: %s" % (snoopy.darNombre(), snoopy.persigueGatos())
Snoopy persigue gatos: False
>>> print "%s odia los perros: %s" % (tom.darNombre(), tom.odiaPerros())
Tom odia los perros: True
>>> print "%s odia los perros: %s" % (felix.darNombre(), felix.odiaPerros())
Felix odia los perros: False


Y esto ha sido una breve introducción al concepto de clases, objetos, instancias y un poco de herencia. Estoy abierto a cualquier tipo de duda o sugerencia.

Saludos, Diego.

6 comentarios:
Write comentarios
  1. Me interesa saber más sobre la herencia múltiple. Crees que me puedes orientar un tanto con ese tema, te lo agradecería :D. Saludos desde Perú.

    ResponderEliminar
    Respuestas
    1. Hola GhianCo Dj, todavía no he tocado nada sobre herencias múltiples, pero más adelante agregaré sobre el tema. Gracias por pasar y participar en el blog. Saludos

      Eliminar
    2. puedes aprender mucho de python en http://ricardonarvaja.info/WEB/OTROS/PYTHON%20DESDE%20CERO/
      ahí enseña herencias múltiples ya voy en la etapa dos y me ha servido me mucho

      Eliminar
  2. Como importo una clase creda?. No me toma la misma en el idle python 2.7 para windows

    ResponderEliminar
  3. No entiendo bien, la clase reemplazaría a la definicion de una base de datos? Por ejemplo si quisiera hacer un abm de clientes, debería definir una clase o manejarme definiendo una base de datos (ej.en sqlite3) No se si me explico. Igualmente excelente tu aporte!!! GRACIAS

    ResponderEliminar
  4. En python 3.x ya no es necesario usar la variable "object" verdad? o si?

    ResponderEliminar

Tu comentario es importante y nos motiva a seguir escribiendo...

Entradas más recientes

© 2014 Mi diario Python. Designed by Bloggertheme9 | Distributed By Gooyaabi Templates
Powered by Blogger.