POO en Python: clases, objetos y encapsulación orientada al dominio

Aprende a modelar entidades de negocio con clases, atributos y métodos, evitando clases anémicas y mejorando cohesión.

La POO en Python sirve para modelar comportamientos del dominio, no para crear jerarquías por moda.

Una clase agrupa estado (atributos) y comportamiento (métodos) con una responsabilidad clara.

El constructor `__init__` define cómo nace un objeto válido; si permites estados inválidos, aparecerán bugs río abajo.

Encapsular reglas dentro de métodos evita lógica dispersa y facilita mantenimiento del sistema.

  • La clase describe el modelo; el objeto representa un caso concreto de ese modelo.
  • `class Cuenta:` define estructura y reglas comunes. `cuenta_ana = Cuenta(...)` crea una instancia con estado propio.
  • Dos objetos de la misma clase comparten comportamiento, pero no necesariamente valores de atributos.
  • Piensa primero qué invariantes debe respetar la entidad antes de escribir métodos.
  • Los métodos deben hacer cumplir reglas del negocio, no solo modificar atributos sin control.

1) Clase vs objeto: plano y instancia

La clase describe el modelo; el objeto representa un caso concreto de ese modelo.

`class Cuenta:` define estructura y reglas comunes. `cuenta_ana = Cuenta(...)` crea una instancia con estado propio.

Dos objetos de la misma clase comparten comportamiento, pero no necesariamente valores de atributos.

Piensa primero qué invariantes debe respetar la entidad antes de escribir métodos.

2) Encapsulación: proteger reglas dentro de métodos

Los métodos deben hacer cumplir reglas del negocio, no solo modificar atributos sin control.

Si cualquier parte del sistema puede cambiar `saldo` directamente, se rompe la consistencia del dominio.

Métodos como `depositar` o `retirar` son puntos de control para validar entradas.

La encapsulación reduce errores y hace más explícitas las operaciones permitidas.

  • Valida reglas dentro de métodos, no fuera.
  • Evita estados imposibles desde el constructor.
  • Mantén métodos cortos y orientados al dominio.
  • Lanza excepciones claras en violaciones de regla.

3) Métodos especiales útiles (`__repr__`, `__str__`)

Representaciones legibles facilitan debugging y logging.

`__repr__` debería describir el objeto de forma útil para desarrolladores.

`__str__` puede orientarse más a salida amigable para usuario/CLI.

Una buena representación acelera diagnóstico cuando inspeccionas objetos en logs o consola.

Python
13

POO en Python: clases, objetos y encapsulación orientada al dominio

Aprende a modelar entidades de negocio con clases, atributos y métodos, evitando clases anémicas y mejorando cohesión.

Código del tema: class Usuario: pass

📘 Teoría

1) Clase vs objeto: plano y instancia

La clase describe el modelo; el objeto representa un caso concreto de ese modelo.

1

`class Cuenta:` define estructura y reglas comunes. `cuenta_ana = Cuenta(...)` crea una instancia con estado propio.

2

Dos objetos de la misma clase comparten comportamiento, pero no necesariamente valores de atributos.

3

Piensa primero qué invariantes debe respetar la entidad antes de escribir métodos.

Definición e instanciación básica
class Cuenta:
    def __init__(self, titular: str, saldo: float = 0.0) -> None:
        self.titular = titular
        self.saldo = saldo


cuenta_ana = Cuenta('Ana', 100.0)
cuenta_luis = Cuenta('Luis', 50.0)
print(cuenta_ana.saldo, cuenta_luis.saldo)

2) Encapsulación: proteger reglas dentro de métodos

Los métodos deben hacer cumplir reglas del negocio, no solo modificar atributos sin control.

Si cualquier parte del sistema puede cambiar `saldo` directamente, se rompe la consistencia del dominio.

Métodos como `depositar` o `retirar` son puntos de control para validar entradas.

La encapsulación reduce errores y hace más explícitas las operaciones permitidas.

  • Valida reglas dentro de métodos, no fuera.
  • Evita estados imposibles desde el constructor.
  • Mantén métodos cortos y orientados al dominio.
  • Lanza excepciones claras en violaciones de regla.
Métodos con validación de negocio
class Cuenta:
    def __init__(self, titular: str, saldo: float = 0.0) -> None:
        self.titular = titular
        self.saldo = saldo

    def depositar(self, cantidad: float) -> None:
        if cantidad <= 0:
            raise ValueError('La cantidad debe ser positiva')
        self.saldo += cantidad

    def retirar(self, cantidad: float) -> None:
        if cantidad <= 0:
            raise ValueError('La cantidad debe ser positiva')
        if cantidad > self.saldo:
            raise ValueError('Saldo insuficiente')
        self.saldo -= cantidad

3) Métodos especiales útiles (`__repr__`, `__str__`)

Representaciones legibles facilitan debugging y logging.

1

`__repr__` debería describir el objeto de forma útil para desarrolladores.

2

`__str__` puede orientarse más a salida amigable para usuario/CLI.

3

Una buena representación acelera diagnóstico cuando inspeccionas objetos en logs o consola.

Representación útil de entidad
class Producto:
    def __init__(self, sku: str, precio: float) -> None:
        self.sku = sku
        self.precio = precio

    def __repr__(self) -> str:
        return f'Producto(sku={self.sku!r}, precio={self.precio})'


print(Producto('KB-001', 39.9))

🧪 Aprende probando

Ejemplo Ejemplo: cuenta bancaria con operaciones controladas Entidad de dominio con invariantes y métodos de negocio explícitos.

🏁 Retos

Reto Reto: añade método `retirar` Implementa una operación de dominio que descuente saldo.

🧰 Recursos

Test

Comprueba tus conocimientos con un test sobre Python.

Test de Python

¿Qué es esto?

Soy Cristian Eslava y a veces hago webs para procrastinar yo y vosotros 😉.

Esta la hice en febrero de 2026 para facilitar el aprendizaje de mis alumnxs. Aprender desarrollo web practicando. La idea es que crezca semanalmente con nuevos temas, tests y retos.

Inspirado en MDN, en W3Schools, en Codepen, en el crack de Manz y en mil sitios de documentación sobre desarrollo web. Quería aportar además de bloques teóricos con ejemplos, la gamificación de los retos y el sistema de test que ya tenía en culTest .

Si te gustó, si no te gustó, si quieres saludarme, o invitarme a 🍻 no dudes en escribirme en cristianeslava@gmail.com .