0Pricing
Python Academy · Lesson

__slots__ and Memory Optimization

Use __slots__ to reduce per-instance memory overhead.

__slots__ and Memory Optimization is a free Python Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Default __dict__ Overhead

By default every Python instance stores attributes in a __dict__ dictionary, which has significant memory overhead — typically 200-400 bytes per instance.

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

Declaring __slots__

Define __slots__ as a sequence of attribute names. Python allocates a fixed-size array instead of a dict, saving memory.

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__

Memory Savings

With __slots__, each instance typically saves 30-50% memory compared to a dict-based instance — significant when creating millions of objects.

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)

No __dict__ by Default

A slotted class has no __dict__, so you cannot add arbitrary attributes after creation.

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

Keeping __dict__ with __slots__

Include "__dict__" in __slots__ to retain a per-instance dict while still pre-declaring common attributes as slots.

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

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

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

__weakref__ in __slots__

Slotted classes lose weak-reference support. Add "__weakref__" to __slots__ to re-enable it.

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>

Inheritance and __slots__

If a parent class does not use __slots__, the child still gets a __dict__. For full savings, the entire hierarchy must define __slots__.

class Base:
    __slots__ = ("x",)

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

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

Benchmarking Memory

Use tracemalloc or pympler to measure actual memory usage before and after adding __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__ and Pickling

Slotted objects can be pickled if you define __getstate__ and __setstate__ or use the default pickle protocol which handles slots automatically from 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 with __slots__ — Python 3.10+

Pass slots=True to @dataclass to automatically generate __slots__.

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

When to Use __slots__

Use __slots__ when: creating millions of instances, memory is constrained, or attribute-access speed is critical. Skip it for general-purpose classes where flexibility matters more.

# 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

Quick Check

What happens when you try to set an attribute not listed in __slots__ on a slotted instance?

Recap

__slots__ replaces the per-instance __dict__ with a fixed array, saving 30-50% memory. Include "__dict__" or "__weakref__" if you need them. The entire inheritance chain must use __slots__ for full savings. In Python 3.10+ use @dataclass(slots=True).

Frequently asked questions

Is the “__slots__ and Memory Optimization” lesson free?

Yes — the full text of “__slots__ and Memory Optimization” is free to read here on the web, and the Python Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO.

What will I learn in “__slots__ and Memory Optimization”?

Use __slots__ to reduce per-instance memory overhead. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Python Academy?

No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “__slots__ and Memory Optimization” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Python Academy lesson?

Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. How Python Classes Are Created
  2. Writing Custom Metaclasses
  3. Descriptors: __get__, __set__, __delete__
  4. __slots__ and Memory Optimization
← Back to Python Academy