
Atributos de Python: entendiendo cómo funcionan 🐍
Los atributos son la base del modelo de objetos de Python, pero la mayoría de los principiantes (e incluso muchos desarrolladores de nivel medio) los usan de forma intuitiva, sin entender qué sucede "bajo el capó". El resultado: comportamiento impredecible del código, consumo de memoria y API espagueti.
Vamos a entender los detalles 👇
1️⃣ Orden de búsqueda (MRO)
Python vive bajo el principio: primero el objeto, luego la clase.
Cuando accedes a
obj.attr, el intérprete primero busca en obj.__dict__. Si no lo encuentra, va a Class.__dict__.Si accidentalmente escribes algo en
obj.attr, crearás un atributo de instancia que ocultará el atributo de clase.class Hero:
weapon = "Sword"
h = Hero()
h.weapon = "Gun" # Ahora h tiene su propia arma, la clase sigue con espadaEsto no es un error, es una característica, pero debes controlarlo. Si quieres cambiar el atributo para todos, modifica la clase.
2️⃣
__dict__ vs __slots__Por defecto, cada objeto tiene
__dict__ — una tabla hash (diccionario) donde se almacenan los atributos. Es flexible, pero consume mucha memoria.Si creas millones de objetos del mismo tipo, usa
__slots__.🔵¿Qué aporta? Evita la creación de
__dict__ para la instancia, fijando rígidamente el conjunto de atributos en memoria (como un array).🔵Beneficio: Reduce un 25-30% el consumo de memoria y acelera ligeramente el acceso.
🔵Costo: Pierdes la capacidad dinámica de agregar nuevos atributos sobre la marcha.
3️⃣ La ilusión de encapsulación
En Python no hay campos "privados". En absoluto.
Las construcciones como
__attribute no son protección de datos, sino name mangling (deformación de nombres). Python simplemente renombra la variable a _ClassName__attribute para evitar que se sobrescriba accidentalmente en las subclases.Si usas
__ esperando que nadie acceda a tus datos, cualquiera que sepa usar dir() lo verá todo. Usa _private (un solo guion bajo) para indicar "no toques, es API interna". Es cuestión de cultura, no del compilador.¿Quieres ocultar datos? Usa un solo guion bajo
_ solo como señal para tus colegas: "No toques esto, es interna". 4️⃣ @property: el getter ético
Nunca hagas en Python getters al estilo Java (
get_value(), set_value()). Si necesitas lógica al acceder a un atributo, usa @property.@property permite convertir un método en un atributo. Mantienes una API limpia (acceso con punto), pero bajo el capó puedes validar datos, registrar accesos o calcular valores sobre la marcha. class DataStorage:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
@value.setter
def value(self, new_val):
if not isinstance(new_val, int):
raise ValueError("Solo int, nena")
self._value = new_valAsí mantienes una interfaz limpia:
obj.value = 10 se ve tan simple como trabajar con un campo normal, pero controlas qué se escribe exactamente.¿Qué otros lugares "mágicos" de Python te generan dudas? Déjalos en los comentarios, los analizaremos. 👇
#anatomia_de_python
Comentarios
0Aún no hay comentarios.
Inicia sesión para participar en la conversación.