advanced

Slots & Hashing

8 min readLast updated: 2026-07-12

Overview

Learn how slots optimizes class memory usage, and master custom class hashing protocols (hash and eq).

Learning Objectives

  • Use slots to prevent default instance dict memory allocation.
  • Make custom object instances hashable.
  • Avoid hash keys lookups conflicts in sets.

Concept Explanation

Python objects store attributes inside dictionary dict buffers. Declaring __slots__ tells Python to use a fixed array instead, saving up to 70% memory. To use instances inside sets, override __eq__ and __hash__ correctly.

Code Examples

Example 1 — Basics

This example introduces the fundamental syntax and concepts.

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

Example 2 — Everyday Usage

This example demonstrates a realistic scenario handling business parameters.

python
class Node:
    __slots__ = ('val', 'next')
    def __init__(self, val):
        self.val = val
        self.next = None

# Node consumes significantly less memory when instantiated millions of times

Example 3 — Advanced Example

This example shows clean, production-grade code structure following senior development standards.

python
class UniqueKey:
    def __init__(self, uid):
        self.uid = uid

    def __eq__(self, other):
        if not isinstance(other, UniqueKey): return False
        return self.uid == other.uid

    def __hash__(self):
        return hash(self.uid)

key1 = UniqueKey(1)
key2 = UniqueKey(1)
s = {key1}
print(key2 in s) # True! Hash matches and eq evaluates True

Visual Flow

The following execution flow represents the step-by-step evaluation inside the interpreter:

text
Instantiate slotted class → Pre-allocate array slots → Map attribute accesses directly by array indices

Common Mistakes

Review these common pitfalls when working with this topic:

  • Trying to add dynamic attributes to slotted instances.
  • Overriding eq without defining hash, which makes instances unhashable.
  • Mutating attributes that are used inside hash collections calculations.
  • Inheriting slotted classes from unslotted parents.

Best Practices

Enforce these Pythonic best practices in your codebase:

❌ Don't
python
class Node:
    def __init__(self, val):
        self.val = val # Allocates dynamic __dict__ dictionary
✅ Do
python
class Node:
    __slots__ = ('val', 'next')
    def __init__(self, val):
        self.val = val # Memory optimized slots

Performance Notes

Keep these optimization guidelines in mind for performance-sensitive hotpaths:

  • slots reduces class instantiation memory usage by up to 60-70% by avoiding dict allocations.
  • Attribute lookups are faster with slots because they bypass dictionary hash table searches.

Quick Revision

Use these key summaries for last-minute revision:

  • slots avoids dictionary allocation in objects.
  • Saves memory and speeds up lookups.
  • Slotted objects cannot have dynamic attributes.
  • Custom hash keys require eq and hash.
  • Hash keys must remain constant.
  • Overriding eq alone makes objects unhashable.