Y ahora si.
Python es un lenguaje de programación orientado a objetos. Lo que significa que hay una construcción en Python llamada clase que nos permite estructurar el código de una manera en particular. Usando clases podemos dotar de consistencia a nuestros programas para que puedan ser utilizados de una manera más limpia. O al ménos, esa es la teoría.
A continuación, voy a tratar de definir los principios de la programación orientada a objetos. Utilizaré lo que ya conozco como diccionarios y módulos con clases y objetos.
Allá vamos.
LOS MÓDULOS SON COMO LOS DICCIONARIOS
Ya sé como crear y usar un diccionario (bueno, estoy en ello) y que éstos me permiten hacer referencia a un elemento a partir de un nombre, lo que significa que si tengo un diccionario con la clave ‘apple’ y quiero obtenerla, hago ésto:
mystuff = {'apple': "I AM APPLES!" (NO ME DEJA ESCRIBIR LA LLAVE DE CIERRE NI CON EL TECLADO EN PANTALLA...WHAT A...????) print mystuff['apple']
Mantengo en mi cabeza la idea de «obtener X a partir de Y» y ahora pienso en los módulos. Hasta el momento he hecho algunos y los he utilizado de acuerdo al siguiente proceso:
- Se que un módulo es un fichero Python con funciones y variables.
- Entonces, importo ese fichero.
- Puedo acceder a las funciones o variables que hay en el módulo escribiendo el operador ‘.‘ (punto).
Imagina que tienes un módulo llamado mystuff.py y contiene la siguiente función llamada apple:
# Esto está dentro de mystuff.py def apple(): print "I AM APPLES!"
Después, puedo usar ese módulo con import y acceder a la función apple:
import mystuff mystuff.apple()
También podría incluir una variable llamada tangerine, así:
def apple(): print "I AM APPLES!" # Esto sólo es una variable tangerine = "Living reflection of a dream"
A continuación, puedo acceder a ésta de la forma:
import mystuff mystuff.apple() print mystuff.tangerine
Volviendo a los diccionarios, debería empezar a darme cuenta de que ésto es similar a usar un diccionario, aunque la síntaxis es diferente. Compara:
mystuff ['apple'] # Obtiene apple del diccionario mystuff.apple() # Obtiene apple del módulo mystuff.tangerine # Lo mismo, pero con una variable
Observo entonces que hay un patrón común en Python:
- Hay relación entre una clave y un valor (clave=valor).
- Obtengo un dato a partir del nombre de la clave.
En el caso del diccionario, la clave es una cadena y la síntaxis es [clave].
En el caso del módulo, la clave es un identificador y la síntaxis es .key. A parte de ésto, son casi iguales.
LAS CLASES SON COMO LOS MÓDULOS
Una forma de ver un módulo es como un diccionario especializado que puede almacenar código Python que puede usar con el operador ‘.’. Python también tiene otra construcción empleada con un propósito similar y que se llama clase. Una clase es una forma de agrupar funciones y datos y guardarlos en un contenedor de manera que se accede a ellos con el operador ‘.’.
Si tuviera que crear una clase con el módulo mystuff, haría algo así:
class MyStuff(object) : def _init_(self) : self.tangerine = "And now a thousand years between" def apple(self) : print "I AM CLASSY APPLES!"
Puede parecer complicado comparado con los módulos y aunque queda pendiente ver algunas diferencias, deberías de ser capaz de apreciar que es como un «mini-módulo» MyStuff que tiene una función apple().
Pueden resultar algo confusos también la función _init_() y el uso de self.tangerine para dar un valor a la variable tangerine.
Esta es la razón por qué las clases se utilizan en lugar de los módulos: se puede tomar la clase anterior y utilizarla para crear muchas de ellas, muchísimas, y que no interfieran entre sí. Con los módulos, al importarlo, sólo hay uno para todo el programa, a no ser que se hagan malabarismos.
Antes de entenderlo, necesito saber qué es un objeto y cómo trabajar con MyStuff tal y como lo hago con el módulo mystuff.py.
LOS OBJETOS SON COMO MINI-IMPORTS
Si una clase es como un mini-módulo, entonces tiene que haber un concepto similar para import, pero aplicado a clases. Este concepto es llamado «instanciar», que es de una forma elegante como decir «crear». Cuando se instancia una clase se obtiene lo que conocemos como un objeto.
La manera de hacerlo es llamar a la clase igual que a una función:
thing = MyStuff () thing.apple () print thing.tangerine
La primera línea es la operación «instancia» y es muy parecido a llamar a una función. Sin embargo, cuando llamamos a ésta, hay una secuencia de eventos que Python coordina. Lo veo usando el código anterior:
- Python busca MyStuff() y ve que es una clase que he definido.
- Python crea un objeto vacío, con todas las funciones que he especificado en la clase usando def.
- Python comprueba si he creado una función mágica _init_ y si está, llama a esa función para inicializar el objeto vacío recién creado.
- En la función _init_ de MyStuff tomo la variable extra self, que es el objeto vacío que Python creó, y asigno valores a las variables utilizándolo igual que hacía con los módulos y otros objetos.
- En éste caso, asigno como valor a self.tangerine la letra de una canción y luego inicializo ese objeto.
- Ahora, Python puede tomar ese objeto y asignarlo a la variable thing para que trabaje con él.
Esto es lo básico de como Python crea los «mini-imports» cuando se llama a una clase como una función. Hay que recordar que ésto no crea una clase, sino que está utilizando una clase como un molde para crear copias de cosas de ese tipo.
En realidad ésto es una idea un tanto inexacta de cómo trabajan las clases y objetos para que se pueda empezar a comprender basándome en lo que ya conozco sobre módulos. La verdad es que las clases y lo objetos divergen de los módulos a partir de éste punto. Es 100% cierto lo siguiente:
- Las CLASES son como moldes o definiciones que permiten crear nuevos mini-módulos.
- Las INSTANCIAS son la forma de crear uno de éstos mini-módulos e importarlos en el mismo momento.
- El mini-módulo creado se llama OBJETO y lo asigno a una variable para trabajar con él.
Las clases y los objetos son muy diferentes de los módulos y lo anterior sólo deve servirme para entender el concepto de clase.
OBTENIENDO COSAS DE THINGS
Hay 3 formas de obtener cosas de things:
# Estilo diccionario mystuff['apples'] (En relidad serían llaves!!!)
# Estilo módulo mystuff.apples() print mystuff.tangerine
# Estilo clase thing = MyStuff () thing.apples () print thing.tangerine
PRIMER EJEMPLO DE CLASES
Debería comenzar a ver las similitudes entre estos tres tipos de contenedores clave = valor y, además, tengo bastantes preguntas que iré resolviendo a partir del próximo ejercicio. Voy a terminar escribiendo algo de código, para ir practicando antes de continuar.
Me da un error en la línea 12 que mareo y cambio cosas (pongo corchetes, espacios, borro, vuelvo a escribir…) y sigue dando error.
……
Al final descubro que aunque dice que el error está en la línea 12, es un problema de definición de los parámetros, el error parece estar al principio…
Necesitaba poner doble guión bajo en la línea 3, de éste modo: def __ init__(self, lyrics):
Ejecutando me da error, ésta vez en la línea 15, pero de nuevo me fijo en las líneas del principio…
En fin. Por hoy termino. Mañana retomo.
Buenas noches!!
Por fiiin. Que no lo veía. Eran los ([]) y no [()]. Hay veces que por una tontería el atasco es absurdo…bueno. Así aprendo para la próxima vez. La verdad es que estaba fijándome en lo que decía el terminal:
TypeError: 'type' object has no attribute ' __getitem__'
¿No es confuso? En fin. A veces sólo hay que fijarse mejor en los detalles del programa. La respuesta estaba ahí.
🙂
PREGUNTAS
P: ¿Por qué necesito self cuando creo _init_ u otra función de la clase?
R: Si no usas self, el código cheese = ‘Frank’ es ambiguo. En ese código no está claro si nos referimos al atributo cheese de la instancia o si es una variable local (?) llamada cheese. Con self.cheese = ‘Frank’ queda muy claro que nos estamos refiriendo al atributo de la instancia self.cheese.




















Debe estar conectado para enviar un comentario.