Contenido del capítulo

En este capítulo aprenderás a crear objetos y a acceder a sus atributos y métodos, entre otras tareas.

Duración estimada de todo el contenido:
Duración del vídeo:
Contiene 6 ejercicios de Python para resolver. Contiene 3 vídeos.
Tabla de contenidos
Logo

    ¿Qué son los objetos?

    Los objetos son elementos creados a partir de una clase. Estos tienen todos los atributos y métodos de la clase a la que pertenecen. Además de esto, tienen la posibilidad de tener algunos propios que no existen en la propia clase.

    En inglés, objeto se dice object.

    Introducción a los objetos con Python
    Introducción a los objetos con Python

    Espacio publicitario

    Sintaxis de un objeto

    Los objetos son creados normalmente dentro de variables. Esto se hace con el fin de tener un contenedor que nos permita manejarlos mediante un identificador (nombre de variable).

    # Declaración de clase
    class NombreClase():
        pass
    
    # Objeto creado a partir de la clase
    objeto = NombreClase()

    Con esto, el objeto llamado objeto (nombre de la variable que lo contiene), tendrá acceso a todo el código definido en la clase. De momento, no es nada más que el pass, pero pronto empezaremos a “darle vida”.

    Para utilizar un atributo o método de una clase, a través de un objeto, se puede hacer mediante el nombre del objeto, un punto y el nombre del método o atributo:

    # Declaración de clase
    class NombreClase():
        # Atributos de clase
        atributo_1 = "valor 1"
        atributo_2 = "valor 2"
    
        # Método
        def metodo_1(self):
            print("Método llamado con el objeto.")
    
    # Objeto creado a partir de la clase
    objeto = NombreClase()
    
    # Llamada al método
    objeto.metodo_1()
    Resultado en la consola
    Método llamado con el objeto.

    El método funciona igual que una función normal, solo que este caso, no se le llama directamente, sino que se hace mediante el propio objeto.

    Estado y comportamiento de los objetos

    Gracias a las dos partes que forman las clases (atributos y métodos), los objetos son capaces de tener lo que conocemos como estado y comportamiento.

    Estado y comportamiento de los objetos en Python
    Estado y comportamiento de los objetos en Python

    Estado de los objetos

    El estado de un objeto es representado mediante sus atributos, es decir, los datos que lo caracterizan. Por ejemplo, un objeto que represente un usuario, podría tener los siguientes atributos:

    • nombre
    • apellidos
    • edad
    • telefono
    • direccion

    Todos estos atributos conformarán el estado del mismo.

    En inglés, “Estado del objeto” se traduce como object state.

    Espacio publicitario

    Comportamiento de los objetos

    El comportamiento de un objeto se representa mediante sus métodos.

    Gracias a los métodos, los objetos pueden realizar acciones de todo tipo. Por ejemplo, un personaje de un videojuego, que estará creado como un objeto, podrá tener capacidades de comportamiento como las que puedes ver a continuación:

    • caminar()
    • saltar()
    • conducir()
    • correr()
    • comer()

    En una aplicación web o de escritorio, los objetos pueden representar usuarios. Estos podrán tener comportamientos como los que ves a continuación:

    • consultar_datos()
    • cambiar_contrasena()
    • iniciar_sesion()
    • cerrar_sesion()
    • eliminar_cuenta()

    Comportamiento del objeto se traduce en inglés como object behavior.

    Identidad de los objetos

    Los objetos, al estar bajo un nombre identificador, podemos decir que cuentan con una identidad única. Gracias a su identidad, podemos referirnos a ellos de forma inequívoca en el código.

    Identidad del objeto se traduce en inglés como object identity.

    En conclusión a todo esto, tenemos estos tres aspectos clave de los objetos:

    • Estado = atributos (variables).
    • Comportamiento = métodos (funciones).
    • Identidad = identificador (nombre del objeto).

    Relación entre estado y comportamiento de los objetos

    El estado y el comportamiento de un objeto están relacionados.

    Imagina una aplicación web de apuestas. En ella, los usuarios están hechos mediante objetos.

    Como seguramente sabrás, en los sitios de apuestas, no pueden acceder personas menores de 18 años (puede que otra edad en algunos países).

    Entonces, estos objetos tendrán que tener un atributo de edad. Si el atributo edad de un usuario es menor de 18 años, no se le dejará acceder a la aplicación web.

    Basándose en ese estado, se determina si el usuario utiliza el comportamiento de un supuesto método llamado permitir_acceso() u otro llamado denegar_acceso().

    Básicamente, quiere decir que el estado es capaz de determinar el comportamiento del objeto en cada momento. También, el comportamiento del objeto puede modificar el estado del mismo. Por ejemplo, en un videojuego, si un personaje camina en unas coordenadas tridimensionales (X, Y, Z) con un método llamado caminar() (comportamiento), sus atributos de posición (estado) irán cambiando, ya que con cada movimiento se encontrará en una ubicación diferente.

    Espacio publicitario

    Instancias de clase

    Llamamos instanciar a un objeto, cuando este es generado a partir de una clase. Puedes reemplazar la palabra instanciar por crear, puesto que son sinónimos.

    Entonces, cuando creo objetos de una clase, puedo decir que estoy instanciando objetos. Es un tecnicismo de la programación orientada a objetos, que debes conocer, ya que su uso está muy extendido y es recomendable utilizarlo.

    A un objeto, de forma técnica se le llama instancia.

    Podemos decir, por ejemplo, que una cadena de caracteres en Python, es una instancia de la clase str.

    En resumen:

    • Instanciar: acción de crear un objeto.
    • Instancia: objeto.

    Instancia se dice en inglés instance, mientras que instanciar es instantiate.

    ¿Cómo se instancia un objeto?

    Instanciar un objeto es muy fácil; solo tienes que darle un nombre a una variable y asignarle la instanciación, que es simplemente el nombre de la clase con unos paréntesis:

    # Se declara la clase Vehiculo
    class Vehiculo():
        # Atributos
        color = None
        longitud_metros = None
        ruedas = 4
    
        # Métodos
        def arrancar(self):
            print("El motor ha arrancado.")
    
        def detener(self):
            print("El motor está detenido.")
    
    # Instanciamos dos objetos de tipo Vehiculo
    objeto_vehiculo_1 = Vehiculo() 
    objeto_vehiculo_2 = Vehiculo()

    Los objetos se instancian fuera de la clase, no los indentes dentro de ella.

    No son parte de la clase, solo un producto de ella.

    Perfecto, ya tenemos los dos primeros objetos instanciados a partir de la clase Vehiculo.

    Por el momento, son dos objetos iguales en cuanto a comportamiento y estado, puesto que no hemos añadido ninguna diferencia entre ellos.

    ¿Dónde se crean los objetos?

    Los objetos son creados solo en tiempo de ejecución. Estos se almacenan en la memoria RAM, hasta que finaliza el programa, en ese momento desaparecen.

    Memoria RAM para los objetos de Python

    Imprimir objetos

    Podemos llevar a cabo una prueba práctica para ver las direcciones de memoria en las que se están guardando los objetos creados. Para ello, hay que “imprimir los objetos” con un print():

    print(objeto_vehiculo_1)
    print(objeto_vehiculo_2)
    Resultado en la consola
    <__main__.Vehiculo object at 0x0000028226985BB0>
    <__main__.Vehiculo object at 0x0000028226985C10>

    Lo que nos aparece son las direcciones de memoria donde se ha almacenado cada objeto.

    En la consola, indica Vehiculo object, en la dirección x, que podemos traducir como “el objeto de clase Vehiculo está en la dirección de memoria x”. Sustituyendo x por el número que aparezca en cada objeto.

    Sin embargo, hasta que no tengas un nivel más alto en Python, esto no te será de ninguna utilidad. Este dato es solo para que empieces a ser consciente de ello.

    Espacio publicitario

    Acceder a los atributos de un objeto

    Acceso a atributos y métodos con los objetos con Python
    Acceso a atributos y métodos con los objetos con Python

    Es posible acceder a un atributo de un objeto de esta forma:

    objeto.atributo

    Aquí tienes un ejemplo con uno de los objetos del código que estamos utilizando en este capítulo:

    objeto_vehiculo_1.ruedas

    Este acceso al atributo nos devolverá el valor que contiene. Este valor, lo puedes almacenar en un contenedor como el de una variable, para hacer lo que quieras con él, o imprimirlo directamente con un print().

    Para imprimir el valor, lo haremos así:

    print(objeto_vehiculo_1.ruedas)
    Resultado en la consola
    4

    Para almacenarlo fuera del propio objeto, lo haremos así:

    ruedas_vehiculo = objeto_vehiculo_1.ruedas

    Reasignar valores a atributos de objetos

    En primera instancia, creamos los objetos con un estado por defecto. Después de esto, es posible variar (reasignar) los valores de los atributos asociados al propio objeto. Recuerda que los atributos en realidad son variables.

    Por ejemplo, supongamos que el primer objeto de tipo Vehiculo, es de color negro, y el segundo de color azul.

    Por defecto, ambos objetos vienen en la clase con un valor None en el atributo color:

    class Vehiculo():
        # Atributos
        color = None
        longitud_metros = None
        ruedas = 4

    Es posible cambiar ese valor por defecto, por el color correspondiente de cada uno.

    Antes de reasignar valores, haz la prueba de imprimir el valor del atributo color, con ambos objetos:

    print(objeto_vehiculo_1.color)
    print(objeto_vehiculo_2.color)
    Resultado en la consola
    None
    None

    Bien, para hacer la reasignación, hazlo como si fueran variables.

    Primero, accede a los dos objetos:

    objeto_vehiculo_1
    objeto_vehiculo_2

    Después, añade un punto para acceder al atributo color de cada uno:

    objeto_vehiculo_1.color
    objeto_vehiculo_2.color

    Ahora, reasigna el valor que quieras. Yo voy a poner estos:

    # Reasignamos un nuevo valor para color
    objeto_vehiculo_1.color = "Negro" 
    objeto_vehiculo_2.color = "Azul" 
    
    # Comprobamos los cambios
    print(objeto_vehiculo_1.color)
    print(objeto_vehiculo_2.color)
    Resultado en la consola
    Negro
    Azul

    En este punto contamos con dos objetos, los cuales tienen muchas cosas en común, pero ya no son exactamente iguales en cuanto a estado; ahora tienen una característica que los hace diferentes.

    Espacio publicitario

    Esta es una de las principales ventajas de la programación orientada a objetos. Mediante el mismo código de la plantilla (clase), podemos aprovechar mucho código, y después solo escribir las variaciones necesarias de cada objeto.

    Crear atributos inexistentes en la clase

    Es posible crear atributos únicos para cada objeto. Estos no estarán disponibles en la clase, serán propios de cada uno. Para hacer esto, solo tienes que crear una asignación de un valor, a un atributo que no esté en el objeto.

    Por ejemplo:

    objeto_vehiculo_1.velocidad_maxima = 161
    
    print(objeto_vehiculo_1.velocidad_maxima)
    Resultado en la consola
    161

    El objeto ahora tiene un atributo que no tendrán el resto de objetos creados con la clase. Si intentas acceder al atributo con el otro objeto, verás que te aparece un error:

    print(objeto_vehiculo_2.velocidad_maxima)
    Error en la consola
    AttributeError: 'Vehiculo' object has no attribute 'velocidad_maxima'
    Error por atributo: el objeto de tipo (clase) 'Vehiculo' no tiene el atributo 'velocidad_maxima'

    Si deseas que este atributo esté disponible en todos los objetos, solo tienes que declararlo en la clase:

    # Se declara la clase Vehiculo
    class Vehiculo():
        # Atributos
        color = None
        longitud_metros = None
        ruedas = 4
        velocidad_maxima = 0
    
        # Métodos
        def arrancar(self):
            print("El motor ha arrancado.")
    
        def detener(self):
            print("El motor está detenido.")
    
    # Creamos dos objetos de tipo Vehiculo
    objeto_vehiculo_1 = Vehiculo()
    objeto_vehiculo_2 = Vehiculo()
    
    # Reasignamos el valor del atributo
    objeto_vehiculo_1.velocidad_maxima = 161
    
    print(objeto_vehiculo_1.velocidad_maxima)
    print(objeto_vehiculo_2.velocidad_maxima)
    Resultado en la consola
    161
    0

    Para la velocidad máxima del segundo vehículo, obtenemos un valor 0, ya que ese es el valor que lleva la clase por defecto para el nuevo atributo. Si no lo reasignas, ese es el valor que va a llevar cualquier nuevo objeto.

    Problemas por atributos externos a la clase

    Ten en cuenta, que si decides añadir atributos inexistentes en la clase, estos pueden presentar sobre todo errores y problemas para mantener el código.

    Si ciertos objetos tienen atributos que otros no, al final deberás aprender o documentar ciertas características de cada objeto. Eso hace que sea muy fácil cometer errores al intentar acceder a un atributo inexistente en cierto objeto, y que sea todo más difícil de mantener.

    Mi recomendación entonces, es que inicialices todos los atributos en la clase. Luego reasígnalos como quieras.

    Espacio publicitario

    Llamar a un método de un objeto

    Para llamar a los métodos de los objetos y ejecutar su código correspondiente, lo debes hacer de la misma forma que llamas a una función, solo que debes hacer referencia al objeto con el que se va a llamar a ese método.

    En el ejemplo que llevamos utilizando hasta ahora, la clase Vehiculo() consta de dos métodos: arrancar() y detener():

        # Métodos
        def arrancar(self):
            print("El motor ha arrancado.")
    
        def detener(self):
            print("El motor está detenido.")

    Llamemos con objeto_vehiculo_1, al método arrancar():

    objeto_vehiculo_1.arrancar()
    Resultado en la consola
    El motor ha arrancado.

    En este caso, el código de los métodos son solo funciones print(), las cuales representan la acción de forma escrita. Sin embargo, si esto fuese un videojuego, podrías añadir al método el código necesario para que el vehículo hiciese un sonido de arranque, y que se viese una animación del vehículo vibrando. Los límites de la imaginación, los pones tú.

    Espacio publicitario




    Espacio publicitario


    Ejercicios de Python para resolver

    Para los siguientes ejercicios, utiliza la siguiente clase:

    class Usuario:
        # Atributos
        nombre = "Sin nombre"
        apellidos = "Sin apellidos"
        edad = 0
        direccion = "Sin dirección"
        telefono = "Sin teléfono"
    
        # Métodos
        def iniciar_sesion(self):
            print("El usuario ha iniciado sesión")
    
        def cerrar_sesion(self):
            print("El usuario ha cerrado sesión")
    
        def cambiar_nombre_perfil(self):
            print("Se cambió el nombre")

    5. Crea tres objetos de tipo Usuario; hazlo con estos identificadores:

    • usuario_1
    • usuario_2
    • usuario_3

    No borres estos tres objetos.

    Los necesitarás para resolver los siguientes ejercicios.

    Simplemente, se pedía que instanciaras tres objetos con estos identificadores:

    usuario_1 = Usuario()
    usuario_2 = Usuario()
    usuario_3 = Usuario()

    6. Asigna un valor al atributo nombre del objeto usuario_1.

    Accedemos al atributo nombre, del objeto usuario_1, y le asignamos un valor:

    usuario_1.nombre = "Enrique"
    print(usuario_1.nombre)
    Resultado en la consola
    Enrique

    7. Asigna un valor de edad a los tres objetos.

    Asignamos una edad a cada uno de los objetos, mediante su atributo edad:

    usuario_1.edad = 32
    usuario_2.edad = 27
    usuario_3.edad = 54
    
    print(usuario_1.edad)
    print(usuario_2.edad)
    print(usuario_3.edad)
    Resultado en la consola
    32
    27
    54

    8. Llama al método iniciar_sesion(), con el objeto usuario_3.

    Hacemos la llamada de esta forma:

    usuario_3.iniciar_sesion()
    Resultado en la consola
    El usuario ha iniciado sesión

    No tienes que poner la llamada al método en un print() para que salga la frase en la consola, puesto que el método ya lleva un print() dentro, que se ejecuta al llamarlo.

    9. Crea un atributo llamado antigüedad, con un valor de 10 (meses), para el objeto usuario_2. Este atributo no estará en la clase, solo lo tendrá este objeto.

    Asignando un valor a un atributo inexistente, se crea en el objeto, sin afectar a la clase o al resto de objetos:

    usuario_2.antiguedad = 10
    print(usuario_2.antiguedad)
    Resultado en la consola
    10

    Por cierto, por tema de la convención de Python, era mejor escribir el nombre del atributo sin diéresis en la “ü”. Era una pequeña trampa.

    10. Encuentra los fallos en el siguiente código:

    class Animal
        especie : None
        nombre : None
        edad : 0
    
        comer(self):
            print(f"El animal está comiendo.")
    
        dormir(self):
            print(f"El animal está durmiendo.")
    
    perro = animal()
    perro.nombre = "Boss"
    print(perro.nombre)
    perro.comer

    Este es el código corregido:

    class Animal:
        especie = None
        nombre = None
        edad = 0
    
        def comer(self):
            print("El animal está comiendo.")
    
        def dormir(self):
            print("El animal está durmiendo.")
    
    perro = Animal()
    perro.nombre = "Boss"
    print(perro.nombre)
    perro.comer()
    • (Línea 1) La clase se define con dos puntos antes de empezar con su bloque de código.
    • (Líneas 2-4)El operador de asignación de los atributos es =, y no :.
    • (Líneas 6 y 9) Los métodos deben declararse con la palabra reservada def.
    • (Líneas 7 y 10)Esto es más una recomendación, que un fallo. Si en una cadena de caracteres no vas a incrustar ninguna expresión, no hay razón para añadir la f de f-strings.
    • (Líneas 1 y 12) Si declaras la clase “Animal”, con la primera letra en mayúscula, no puedes llamarla después como “animal”. Python es case sensitive (distingue entre mayúsculas y minúsculas).
    • (Línea 15) Los atributos se llaman sin paréntesis, pero los métodos, al igual que las funciones, requieren ser invocados con ().


    Espacio publicitario