0Pricing
Python Academy · Lección

__slots__ y optimización de memoria

Utilice __slots__ para reducir la sobrecarga de memoria por instancia.

__slots__ y optimización de memoria es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.

La sobrecarga predeterminada de __dict__

De forma predeterminada, cada instancia de Python almacena sus atributos en un diccionario __dict__, que supone una sobrecarga de memoria considerable: normalmente, entre 200 y 400 bytes por instancia.

import sys

class Point:
    def __init__(self, x, y): self.x, self.y = x, y

p = Point(1, 2)
print(sys.getsizeof(p.__dict__))   # ~200 bytes

Declaración de __slots__

Defina __slots__ como una secuencia de nombres de atributos. Python asigna una matriz de tamaño fijo en lugar de un diccionario, lo que permite ahorrar memoria.

class SlottedPoint:
    __slots__ = ("x", "y")

    def __init__(self, x, y):
        self.x = x
        self.y = y

p = SlottedPoint(1, 2)
print(p.x, p.y)   # 1 2
# p.z = 3   # AttributeError: no __dict__

Ahorro de memoria

Con __slots__, cada instancia suele ahorrar entre un 30 % y un 50 % de memoria en comparación con una instancia basada en un diccionario, una diferencia importante al crear millones de objetos.

import sys

class Reg:
    def __init__(self, x, y): self.x, self.y = x, y

class Slotted:
    __slots__ = ("x","y")
    def __init__(self, x, y): self.x, self.y = x, y

print(sys.getsizeof(Reg(1,2)))      # ~56 bytes + ~200 dict
print(sys.getsizeof(Slotted(1,2)))  # ~56 bytes (no dict)

Sin __dict__ de forma predeterminada

Una clase que usa slots no tiene __dict__, por lo que no puede añadir atributos arbitrarios después de crearla.

class Config:
    __slots__ = ("host", "port")
    def __init__(self, h, p): self.host, self.port = h, p

c = Config("localhost", 8080)
# c.debug = True   # AttributeError
print(hasattr(c, "__dict__"))   # False

Conservar __dict__ con __slots__

Incluya "__dict__" en __slots__ para conservar un diccionario por instancia y, al mismo tiempo, declarar previamente los atributos comunes como slots.

class Hybrid:
    __slots__ = ("x", "__dict__")

    def __init__(self, x):
        self.x = x

h = Hybrid(1)
h.extra = "dynamic"   # allowed
print(h.extra)

__weakref__ en __slots__

Las clases que usan slots pierden la compatibilidad con las referencias débiles. Añada "__weakref__" a __slots__ para volver a habilitarla.

import weakref

class Node:
    __slots__ = ("value", "__weakref__")
    def __init__(self, v): self.value = v

n = Node(42)
ref = weakref.ref(n)
print(ref())  # <Node object>

Herencia y __slots__

Si una clase principal no usa __slots__, la clase secundaria sigue teniendo un __dict__. Para obtener el máximo ahorro, toda la jerarquía debe definir __slots__.

class Base:
    __slots__ = ("x",)

class Child(Base):
    __slots__ = ("y",)   # no __dict__

class WithoutSlots(Base):
    pass   # gets __dict__ from object

Medición de la memoria

Use tracemalloc o pympler para medir el uso real de memoria antes y después de añadir __slots__.

import tracemalloc

tracemalloc.start()
points = [SlottedPoint(i, i) for i in range(100_000)]
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
print(f"Peak: {peak/1024/1024:.1f} MB")

__slots__ y la serialización con pickle

Los objetos que usan slots pueden serializarse con pickle si define __getstate__ y __setstate__, o si usa el protocolo de pickle predeterminado, que gestiona los slots automáticamente desde Python 3.

import pickle

class Point:
    __slots__ = ("x", "y")
    def __init__(self, x, y): self.x, self.y = x, y

p = Point(3, 4)
data = pickle.dumps(p)
p2 = pickle.loads(data)
print(p2.x, p2.y)   # 3 4

dataclasses con __slots__ — Python 3.10+

Pase slots=True a @dataclass para generar __slots__ automáticamente.

from dataclasses import dataclass

@dataclass(slots=True)
class Vector:
    x: float
    y: float

v = Vector(1.0, 2.0)
print(v.x, v.y)   # 1.0 2.0
print(hasattr(v, "__dict__"))   # False

Cuándo usar __slots__

Use __slots__ cuando cree millones de instancias, la memoria sea limitada o la velocidad de acceso a los atributos sea crítica. Omítalo en clases de propósito general cuando la flexibilidad sea más importante.

# Good candidates:
# - Nodes in a large graph or tree
# - Records in a large dataset
# - High-frequency event objects

# Bad candidates:
# - Configuration objects added to ad-hoc
# - Classes that mix-in dynamic attributes

Comprobación rápida

¿Qué ocurre cuando intenta establecer, en una instancia que usa slots, un atributo que no aparece en __slots__?

Repaso

__slots__ reemplaza el __dict__ de cada instancia por una matriz de tamaño fijo, lo que permite ahorrar entre un 30 % y un 50 % de memoria. Incluya "__dict__" o "__weakref__" si los necesita. Toda la cadena de herencia debe usar __slots__ para obtener el máximo ahorro. En Python 3.10 y versiones posteriores, use @dataclass(slots=True).

Preguntas frecuentes

¿La lección «__slots__ y optimización de memoria» es gratis?

Sí — el texto completo de «__slots__ y optimización de memoria» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.

¿Qué aprenderé en «__slots__ y optimización de memoria»?

Utilice __slots__ para reducir la sobrecarga de memoria por instancia. Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Python Academy?

No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «__slots__ y optimización de memoria»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Python Academy?

Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Cómo se crean las clases de Python
  2. Escritura de metaclases personalizadas
  3. Descriptores: __get__, __set__, __delete__
  4. __slots__ y optimización de memoria
← Volver a Python Academy