🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

Introducción a las Clases de Python y la Programación Orientada a Objetos [Guía para Principiantes]

Para ejecutar Python desde el símbolo del sistema o PowerShell en tu PC, necesitas descargar e instalar Python.
Si aún no lo has hecho, consulta el artículo Instalación de Python y configuración del entorno de desarrollo para instalar Python.

¡Hola a todos los que recién se inician en el mundo del desarrollo web! En esta ocasión, vamos a explicar de la forma más clara posible un concepto fundamental en muchos lenguajes de programación: la Programación Orientada a Objetos (POO) y su pilar en Python, las clases. No hay que temer a los términos técnicos. Al terminar de leer este artículo, seguro que pensarás: "¡Ah, ya lo entiendo!".

El objetivo principal de este artículo es que experimentes la alegría de ver el código funcionar. Dejaremos la teoría complicada para después. ¡Empecemos por copiar, pegar y sentir la comodidad de la programación orientada a objetos!


Para empezar, ¿qué es la Programación Orientada a Objetos?

Cuando escuchas "Orientado a Objetos", puede sonar complicado, ¿verdad? Pero en realidad, es un concepto que nos rodea en nuestra vida diaria.

Una analogía muy común es la de un "molde para galletas" y una "galleta".

En el mundo de la programación, una vez que creas este "plano" (la clase), puedes producir de manera eficiente y masiva "cosas" concretas (objetos). Este es el concepto fundamental de la POO. En un sitio web, tratar elementos como "usuarios", "artículos de blog" o "productos" como objetos individuales permite organizar sistemas complejos de forma clara y ordenada.


Conceptos básicos de las clases en Python: Creemos un plano

Muy bien, vamos a sumergirnos y a crear un "plano", o una clase, en Python. Usaremos el tema de los perros (Perro) para esta sección.

1. La clase más simple

Primero, definamos una clase vacía. Incluso así, ya es un "plano" válido.

# Define una clase (plano) llamada Perro
class Perro:
    pass # pass significa "no hacer nada". Se usa cuando se requiere una declaración sintácticamente pero no hay código que ejecutar.

# Crea un objeto (instancia) concreto de perro a partir de la clase Perro
mi_perro = Perro()

# Imprimamos qué es mi_perro
print(mi_perro)

Resultado de la ejecución:

<__main__.Perro object at 0x10e28a2d0>

Al ver el resultado, puedes notar que se creó un objeto de la clase `Perro`. (La parte `0x...` variará según tu entorno de ejecución).


2. Dando personalidad con el método `__init__`

A continuación, al igual que añadiríamos chispas de chocolate a una galleta, vamos a darle a nuestro perro información específica (llamada propiedades o atributos) como un "nombre" y una "raza". Para ello, usamos un método especial (una función dentro de una clase) llamado `__init__`. Este es un método de inicialización que se ejecuta automáticamente en el momento en que se crea un objeto.

class Perro:
    # El método de inicialización, se llama automáticamente al crear un objeto
    def __init__(self, nombre, raza):
        # Guarda datos en el objeto usando el formato self.nombre_variable
        self.nombre = nombre
        self.raza = raza
        print(f"¡Ha nacido {self.nombre} ({self.raza})!")

# Crea un objeto "Shiba Inu" llamado "Pochi"
perro1 = Perro("Pochi", "Shiba Inu")

# Crea un objeto "Akita" llamado "Hachi"
perro2 = Perro("Hachi", "Akita")

# Mostremos el nombre y la raza de cada uno
print(f"Nombre del primer perro: {perro1.nombre}")
print(f"Raza del primer perro: {perro1.raza}")
print(f"Nombre del segundo perro: {perro2.nombre}")
print(f"Raza del segundo perro: {perro2.raza}")

El primer argumento de `__init__`, `self`, es una palabra clave especial que se refiere a la instancia que se está creando. Piénsalo como una convención. Al escribir `self.nombre = nombre`, estás vinculando datos al objeto, como si dijeras "el nombre de este objeto es...".

Resultado de la ejecución:

¡Ha nacido Pochi (Shiba Inu)!
¡Ha nacido Hachi (Akita)!
Nombre del primer perro: Pochi
Raza del primer perro: Shiba Inu
Nombre del segundo perro: Hachi
Raza del segundo perro: Akita

Simplemente llamando a la clase como `Perro("Pochi", "Shiba Inu")`, se ejecuta el método `__init__`, creando objetos con su respectiva información. Puedes acceder a la información que contiene un objeto usando un `.` (punto), como en `perro1.nombre`.


3. Definiendo comportamiento con métodos

Los objetos no solo pueden tener datos (atributos), sino también "comportamientos" (métodos). Para un perro, añadamos el comportamiento de "ladrar".

class Perro:
    def __init__(self, nombre, raza):
        self.nombre = nombre
        self.raza = raza

    # Añade un comportamiento (método) para que el perro ladre
    def ladrar(self):
        return f"{self.nombre}: ¡Guau, guau!"

# Crea un objeto
mi_perro = Perro("Koro", "Mestizo")

# Llama al método ladrar
saludo = mi_perro.ladrar()
print(saludo)

Simplemente defines una función dentro de la clase usando `def`. De nuevo, no olvides incluir `self` como primer argumento. A través de `self`, puedes acceder al propio nombre del objeto (`self.nombre`).

Resultado de la ejecución:

Koro: ¡Guau, guau!

Tema avanzado: Reutilizando planos con la "herencia" de clases

Aquí es donde la programación orientada a objetos se vuelve realmente poderosa. Usando un mecanismo llamado "herencia", puedes crear fácilmente una nueva clase añadiendo o modificando funcionalidades basadas en una clase existente (plano).

Por ejemplo, creemos una nueva clase "PerroGuia" basada en nuestra clase anterior `Perro`. Un perro guía es un tipo de perro, por lo que tiene un "nombre" y una "raza" y la capacidad básica de "ladrar". Además, tiene el trabajo especial (método) de "ayudar a las personas".

# La clase padre base (superclase)
class Perro:
    def __init__(self, nombre, raza):
        self.nombre = nombre
        self.raza = raza
        print(f"Ha nacido un perro llamado {self.nombre}. La raza es {self.raza}.")

    def ladrar(self):
        return f"{self.nombre}: ¡Guau!"

# Crea una nueva clase hija (subclase) que hereda de la clase Perro
class PerroGuia(Perro): # Escribe el nombre de la clase padre entre paréntesis
    def asistir(self):
        return f"{self.nombre} está guiando a una persona de forma segura."

# Crea un objeto PerroGuia
perro_g = PerroGuia("Elle", "Labrador Retriever")

# También se pueden usar los métodos de la clase padre (Perro)
print(perro_g.ladrar())

# El método único añadido en la clase hija (PerroGuia)
print(perro_g.asistir())

Simplemente escribiendo el nombre de la clase base entre paréntesis después del nombre de la nueva clase, como `class PerroGuia(Perro):`, la herencia está completa. Así de fácil, `PerroGuia` hereda todos los atributos (`nombre`, `raza`) y métodos (`ladrar`) de `Perro`. Esto aumenta enormemente la reutilización del código y es muy eficiente.

Resultado de la ejecución:

Ha nacido un perro llamado Elle. La raza es Labrador Retriever.
Elle: ¡Guau!
Elle está guiando a una persona de forma segura.

Ejemplo práctico: Una clase para gestionar entradas de blog

Ahora, veamos un ejemplo más cercano a un escenario real de producción web. Crearemos una clase `EntradaBlog` para gestionar artículos en un sitio de blogs. Un artículo tiene un "título", "contenido" y "autor", y le daremos una función para "mostrar la entrada".

import textwrap

class EntradaBlog:
    def __init__(self, titulo, contenido, autor):
        self.titulo = titulo
        self.contenido = contenido
        self.autor = autor

    # Un método para mostrar la información del artículo de forma ordenada
    def mostrar(self):
        print("--------------------")
        print(f"Título: {self.titulo}")
        print(f"Autor: {self.autor}")
        print("--- Contenido ---")
        # Ajusta y muestra texto largo
        print(textwrap.fill(self.contenido, width=40))
        print("--------------------")

# Crea múltiples objetos de entradas de blog
post1 = EntradaBlog(
    "Introducción a las Clases de Python",
    "La programación orientada a objetos es una forma de pensar en la que se ensamblan los programas como si fueran componentes. Una clase es un plano y un objeto es la instancia real.",
    "Taro Yamada"
)

post2 = EntradaBlog(
    "Conceptos Básicos de Diseño Web",
    "Un buen diseño no solo considera la belleza visual, sino que prioriza la facilidad de uso para el usuario. El espaciado y la paleta de colores son cruciales.",
    "Hanako Sato"
)

# Muestra los artículos
post1.mostrar()
post2.mostrar()

Al tratar cada artículo como un objeto de esta manera, los datos (como el título) y el comportamiento (la función de mostrar) se agrupan, facilitando mucho la gestión.

Resultado de la ejecución:

--------------------
Título: Introducción a las Clases de Python
Autor: Taro Yamada
--- Contenido ---
La programación orientada a objetos es
una forma de pensar en la que se
ensamblan los programas como si fueran
componentes. Una clase es un plano y un
objeto es la instancia real.
--------------------
--------------------
Título: Conceptos Básicos de Diseño Web
Autor: Hanako Sato
--- Contenido ---
Un buen diseño no solo considera la
belleza visual, sino que prioriza la
facilidad de uso para el usuario. El
espaciado y la paleta de colores son
cruciales.
--------------------

[¡Pruébalo tú mismo!] Un ejemplo de código Python completo

¡La espera ha terminado! Aquí te presentamos el código completo de un "Programa de Gestión de Usuarios" que reúne todo lo que hemos visto. Puedes guardar este código como un archivo `.py` y ejecutarlo desde la terminal (o símbolo del sistema) de tu ordenador. ¡Anímate y experimenta la "alegría de verlo funcionar"!

Cómo ejecutarlo

  1. Copia todo el bloque de código de abajo.
  2. Pégalo en un editor de texto (como VSCode) y guárdalo con el nombre `gestor_usuarios.py`.
  3. Abre tu terminal y navega hasta el directorio donde guardaste el archivo.
  4. Escribe `python gestor_usuarios.py` y presiona Enter.

Si no tienes Python instalado en tu PC, por favor descárgalo desde python.org.

# gestor_usuarios.py

class Usuario:
    """
    Una clase para representar la información de un usuario de un sitio web
    """
    def __init__(self, id_usuario, nombre, email):
        self.id_usuario = id_usuario
        self.nombre = nombre
        self.email = email
        self.esta_activo = True # Usuario activo por defecto

    def obtener_perfil(self):
        """
        Formatea y devuelve la información del perfil del usuario
        """
        estado = "Activo" if self.esta_activo else "Inactivo"
        return f"ID: {self.id_usuario}\nNombre: {self.nombre}\nEmail: {self.email}\nEstado: {estado}"

    def desactivar(self):
        """
        Desactiva al usuario
        """
        self.esta_activo = False
        print(f"El usuario '{self.nombre}' ha sido desactivado.")


# La parte que ejecuta el proceso principal
if __name__ == "__main__":
    # Crea múltiples objetos de usuario
    usuario1 = Usuario("web-creator", "Taro Tanaka", "tanaka@example.com")
    usuario2 = Usuario("designer-sato", "Hanako Sato", "sato@example.com")

    # Muestra los perfiles
    print("--- Lista de Usuarios ---")
    print(usuario1.obtener_perfil())
    print("-" * 20)
    print(usuario2.obtener_perfil())
    print("\n" + "=" * 20 + "\n")

    # Intentemos desactivar a un usuario
    usuario2.desactivar()

    print("\n--- Lista de Usuarios Después de los Cambios ---")
    print(usuario1.obtener_perfil())
    print("-" * 20)
    print(usuario2.obtener_perfil())

Cuando ejecutes este código, tu terminal debería mostrar lo siguiente:

Ejemplo de salida:

--- Lista de Usuarios ---
ID: web-creator
Nombre: Taro Tanaka
Email: tanaka@example.com
Estado: Activo
--------------------
ID: designer-sato
Nombre: Hanako Sato
Email: sato@example.com
Estado: Activo

====================

El usuario 'Hanako Sato' ha sido desactivado.

--- Lista de Usuarios Después de los Cambios ---
ID: web-creator
Nombre: Taro Tanaka
Email: tanaka@example.com
Estado: Activo
--------------------
ID: designer-sato
Nombre: Hanako Sato
Email: sato@example.com
Estado: Inactivo

¿Qué te parece? Al usar clases, la información del usuario y sus operaciones relacionadas (como la desactivación) se agrupan de forma ordenada, lo que probablemente te hace sentir que el código es más fácil de leer.


Puntos a tener en cuenta / Errores comunes

Finalmente, introduzcamos algunos puntos en los que los principiantes suelen tropezar al trabajar con clases.


Hacia el siguiente paso

Ahora que entiendes los conceptos básicos de las clases y la programación orientada a objetos, probemos a usar las útiles bibliotecas estándar de Python. Manejar fechas y horas es una tarea muy común en programación.

En el próximo artículo, aprenderemos a obtener la fecha actual y a realizar cálculos con fechas utilizando el módulo `datetime`.

→ Cómo manejar fechas y horas con el módulo datetime