Skip to content

registry pattern

The registry pattern is a design pattern that keeps a central lookup table mapping keys to objects, so any part of a program can find a component by name instead of holding a direct reference to it.

A registry needs only two operations: one that stores a value under a key, and one that returns the value for a given key. The keys are usually strings or types, and the values range from a single shared service to whole classes waiting to be instantiated.

When the values are classes, a factory usually wraps the registry, looking up the key and returning a new instance. The registry sits at a known location, such as a module-level dictionary, so callers reach it without receiving it as an argument.

Its most common use is a plugin architecture. Each implementation registers itself under a name as it loads, and the application resolves that name later. This inverts the usual direction of a dependency, because the core code never imports the plugins. Adding a new implementation then means adding a file rather than editing a hand-written chain of conditionals:

Two side by side code panels. The left runs an if/elif chain testing json, csv, and xml in turn. The right holds a WRITERS dict of the same three formats and one keyed lookup.
One Keyed Lookup Replaces the Whole if/elif Chain

Registration itself happens in a few standard ways:

  • Explicit call: The registering module calls a function such as register(key, value) at import time.
  • Decorator: A decorator attached to a class or function stores the object under a key and returns it unchanged.
  • Subclass hook: A base class records every subclass automatically as each one is defined, through a metaclass or .__init_subclass__().
  • Entry point: The packaging metadata of an installed distribution declares the implementation, which lets a separate package extend the application.

Python builds registries into several standard library tools. The functools module’s singledispatch() exposes a read-only .registry mapping of types to implementations, filled by its .register() decorator. The codecs module keeps a codec registry that lookup() searches by encoding name.

Because a registry is reachable from everywhere, it attracts the same criticisms as a singleton. It holds mutable global state and hides dependencies that dependency injection would make explicit. A missing key also surfaces at runtime rather than at import time, and registration order matters, since a lookup that runs before the registering module is imported finds nothing.

Step through the import order of a small plugin application below to watch the registry fill one entry at a time, then resolve a name before and after its module loads:

Interactive diagram — enable JavaScript to view.
The Factory Method Pattern and Its Implementation in Python

Tutorial

The Factory Method Pattern and Its Implementation in Python

In this Python tutorial, you'll learn about the Factory Method design pattern and its implementation. You'll understand the components of Factory Method, when to use it, and how to modify existing code to leverage it. You'll also see a general purpose implementation of Factory Method in Python.

intermediate best-practices

For additional information on related topics, take a look at the following resources:


By Martin Breuss • Updated Aug. 26, 2026