Clases y objetos
En Python todo es un objeto. Por ejemplo, todas las variables para almacenar
textos son objetos del tipo str
(les decimos strings).
Hemos visto ya que estos objetos tienen propiedades y funciones (upper
,
lower
, strip
, etc).
¿Te preguntaste dónde estan definidas esas funciones?
¿Quien decide que puede y que no puede hacerse con un objeto?
La respuestas a todo son las clases. En Python (y en cualquier lenguaje que use Programación Orientada a Objetos) podemos definir nuestros propios tipos de objetos. Cuando los definimos hacemos la elección de que como funcionará y que propiedades y funciones incluirá.
Mi primera clase
Veamos un ejemplo basico. Queremos definir un tipo de dato nuevo: Persona
.
1class Persona:
2 def __init__(self, nombre, apellido):
3 self.nombre = nombre
4 self.apellido = apellido
5
6# ------------------- FIN DE LA CLASE ------------------------------------
7
8# Crear nuestros objetos de tipo Persona
9juan = Persona(nombre='juan carlos', apellido='perez')
10pedro = Persona(nombre='pedro ', apellido='gomez')
11luis = Persona('Luis', 'Velez ')
12
13# Ver el tipo
14type(juan)
15# imprime <class '__main__.Persona'>
16
17# imprimir propiedades de nuestro objeto
18print(f'{luis.nombre} {luis.apellido}')
19'Luis Velez'
Anatomia de una clase
class
es una palabra reservada de Python (no la podemos usar como nombre de variable) que usamos para indicar que estamos definiendo una clase.Despues de
class
agregamos el nombre de nuestra clase. Se deben cumplir las mismas reglas que para los nombres de variables (no pueden empezar con números, no pueden tener espacios, etc). Se suele usar aqui el formato CamelCase y siempre con mayúscula inicial. No es obligatorio.Despues del nombre de la clase podemos colocar parentesis (no es obligatorio). Se usarán en caso de querer aprovechar algo llamado Herencia que veremos más adelante.
Finalmente agregamos : (dos puntos) para indicar que terminamos de definir el encabezado de la clase y vamos a comenzar con el bloque de código de ella.
El código de la clase debe estar tabulado hacia la derecha. Esta es una de las grandes diferencias que Python tiene con los demás lenguajes de programación. El código propio de la clase comienza tabulado y termina cuando el código vuelve a la izquierda. Muchos otros lenguajes de programación usan las llaves
{}
para delimitar donde empiezan y terminan los bloques de código.Dentro del código de la clase debemos definir las propiedades y funciones que queremos que tengan nuestros objetos. Podemos agregar tantas propiedades y funciones como sean necesarias. Veremos más detalles a continuación.
__init__
es hasta aquí nuestra única función (nos damos cuenta porque usa eldef
que ya conocemos junto a un grupo de parámetros). Cuando veamos estos guiones bajos dobles debemos interpretar que es una herramienta interna de Python. En este caso, todas las clases tienen una función de inicialización (y siempre se llama__init__
). Ser la función inicializadora quiere decir que se va a ejecutar cuando los usuarios de la clase la usen para construir un objeto de este tipo.self
es el primer parámetro de la función__init__
. Hablaremos en particular de este parámetro más adelante. Por ahora podemos decir que es obligatorio que todas las funciones de las clases tengan un parametro que represente a cada objeto creado con esta clase. Es por esto que veremos aself
en (casi, hay situaciones especiales) todas las funciones de una clase.Una vez definida la clase (y terminada anulando la tabulación y volviendo a la izquierda el código), esta se puede llamar simplemente con su nombre y entre paréntesis todos los parámetros que se hayan definido en
__init__
(despues deself
).
Clases y objetos
Las clases se usan para definir el comportamiento de los objetos que podremos crear a partir de ellas. Al proceso de crear un nuevo objeto se le dice instanciar y a cada objeto se le puede llamar instancia. En las siguientes líneas …
juan = Persona(nombre='juan carlos', apellido='perez')
pedro = Persona(nombre='pedro', apellido='gomez')
# como en las funciones, no es obligatorio nombrar los parámetros
luis = Persona('Luis', 'Velez ')
se crean tres instancias del tipo Persona
. Cada una de ellas es un objeto distinto y por
lo tanto las propiedades que contienen son independientes y se procesan de manera aislada.
print(juan.nombre)
'juan carlos'
print(pedro.nombre)
'pedro'
Podemos pensar a los objetos o instancias como una versión concreta de una clase.
¿self
?
Salvo algunas excepciones todas las funciones de las clases deben tener como primer
parámetro a self
. De esta forma, todo el objeto estará disponible dentro de cada
función de la clase. Esto es obligatorio y olvidar colocarla generará errores difíciles
de detectar en nuestras primeras experiencias con clases.
Cuando llamamos a funciones de la clase que usan self
, no debemos pasar nada en
lugar de este paràmetro. Debemos ignorarlo cuando estamos usando nuestro objeto.
Esto es visible en todos los ejemplos usados en este manual.
Contenido de un clase
Dentro de la clase podemos definir las propiedades y funciones que nuestros objetos tendrán cuando sean instanciados.
Cuando escribimos self.PROPIEDAD = VALOR
estamos indicando que los usuarios podrán usar
estas propiedades en los objetos definidos.
Estas líneas …
class Persona:
def __init__(self, nombre, apellido):
self.nombre = nombre
self.apellido = apellido
indican que todos los objetos de tipo Persona
tendrán disponibles las propiedades
nombre
y apellido
. Además el valor de ellas será inicializado con los parámetros
que usuario pase al construir estos objetos.
Al no tener valores predeterminados (funciona igual que las funciones) ambas propiedades
son obligatorias. Si intentamos crear una Persona
con algo como:
juan = Persona(nombre='juan carlos')
obtendremos un error, el apellido
es
obligatorio.
Asi como estas propiedades están definidas además de poder ser leidas como hemos visto, tambien pueden modificarse libremente.
diego = Persona('Diego', 'Algun apellido')
diego.apellido = 'Solis'
print(diego.apellido)
'Solis'
Esta forma de definir y usar las propiedades en nuestros objetos es poco segura. En nuestra clase, el siguiente comportamiento si esta permitido:
diego = Persona('Diego', 'Algun apellido')
diego.apellido = 17 # sería bueno evitar esto
print(diego.apellido)
17
Tareas
Crear una clase llamada
Auto
que se inicialice con algunas propiedades obligatorias y otras opcionales