En Python, todo es un objeto. En esta primera parte revisamos cómo definir clases, crear instancias, usar el constructor __init__ y distinguir atributos de clase y de instancia. La meta es comprender la semántica básica y las diferencias respecto a Java (menos ceremonia, más expresividad).
1) ¿Qué es una clase?
Una clase define un tipo (molde) a partir del cual se crean instancias (objetos).
En Python, la palabra clave es class y no se declaran tipos de campo explícitos.
2) Crear clases (definición mínima)
class Punto:passp = Punto() # instanciaprint(type(p)) # <class '__main__.Punto'>
Nota:pass indica un bloque vacío. Podemos añadir atributos dinámicamente en tiempo de ejecución (no recomendado sin control).
3) Constructores con __init__
class Punto:def__init__(self, x: float, y: float):self.x = x # atributo de instanciaself.y = yp = Punto(3.0, 4.0)print(p.x, p.y)
Idea:self es la referencia a la instancia (explícita en Python). Equivale al this de Java, pero se escribe como primer parámetro.
4) Atributos de clase vs. de instancia
class Circulo: pi =3.14159# atributo de CLASE (compartido)def__init__(self, radio: float):self.radio = radio # atributo de INSTANCIAc1 = Circulo(1.0)c2 = Circulo(2.0)print(Circulo.pi, c1.radio, c2.radio)
Regla:
- Clase: espacio de nombres común (constantes, configuración).
- Instancia: datos propios de cada objeto.
5) Métodos de instancia y de clase
class Circulo: pi =3.14159def__init__(self, radio):self.radio = radiodef area(self): # método de instanciareturn Circulo.pi *self.radio**2@classmethoddef unidad(cls): # método de clase (fábrica)return cls(1.0)c = Circulo.unidad()print(round(c.area(), 3))
Distinción:
- Instancia: usa self (estado del objeto).
- Clase: usa cls (opera a nivel de tipo; factorías, configuraciones).
6) Métodos mágicos básicos: __str__ y __repr__
class Punto:def__init__(self, x, y):self.x = x;self.y = ydef__repr__(self):returnf"Punto(x={self.x}, y={self.y})"def__str__(self):returnf"({self.x}, {self.y})"p = Punto(1, 2)print(repr(p)) # representación para desarrolladoresprint(p) # amigable para usuarios
Convención:__repr__ debe ser no ambigua; __str__ es legible.
💭 Checkpoint (reflexión)
¿Qué diferencia hay entre un atributo de clase y uno de instancia?
¿Para qué sirve @classmethod? ¿En qué se distingue de un método de instancia?
¿Por qué tener __repr__ y __str__ distintos puede ayudar en depuración y presentación?