Skip to content

Repository files navigation

python-patterns

A collection of design patterns and idioms in Python.

Remember that each pattern has its own trade-offs. And you need to pay attention more to why you're choosing a certain pattern than to how to implement it.

Creational Patterns

Patterns that deal with object creation — abstracting and controlling how instances are made.

graph LR
Client -->|requests object| AbstractFactory
AbstractFactory -->|delegates to| ConcreteFactory
ConcreteFactory -->|produces| Product
Builder -->|step-by-step| Director
Director -->|returns| BuiltObject
FactoryMethod -->|subclass decides| ConcreteProduct
Pool -->|reuses| PooledInstance
Loading
PatternDescription
abstract_factoryuse a generic function with specific factories
borga singleton with shared-state among instances
builderinstead of using multiple constructors, builder object receives parameters and returns constructed objects
factorydelegate a specialized function/method to create instances
lazy_evaluationlazily-evaluated property pattern in Python
poolpreinstantiate and maintain a group of instances of the same type
prototypeuse a factory and clones of a prototype for new instances (if instantiation is expensive)

Structural Patterns

Patterns that define how classes and objects are composed to form larger, flexible structures.

graph TD
Client --> Facade
Facade --> SubsystemA
Facade --> SubsystemB
Facade --> SubsystemC
Client2 --> Adapter
Adapter --> LegacyService
Client3 --> Proxy
Proxy -->|controls access to| RealSubject
Component --> Composite
Composite --> Leaf1
Composite --> Leaf2
Loading
PatternDescription
3-tierdata<->business logic<->presentation separation (strict relationships)
adapteradapt one interface to another using a white-list
bridgea client-provider middleman to soften interface changes
compositelets clients treat individual objects and compositions uniformly
decoratorwrap functionality with other functionality in order to affect outputs
facadeuse one class as an API to a number of others
flyweighttransparently reuse existing instances of objects with similar/identical state
front_controllersingle handler requests coming to the application
mvcmodel<->view<->controller (non-strict relationships)
proxyan object funnels operations to something else

Behavioral Patterns

Patterns concerned with communication and responsibility between objects.

graph LR
Sender -->|sends event| Observer1
Sender -->|sends event| Observer2
Request --> Handler1
Handler1 -->|passes if unhandled| Handler2
Handler2 -->|passes if unhandled| Handler3
Context -->|delegates to| Strategy
Strategy -->|executes| Algorithm
Originator -->|saves state to| Memento
Caretaker -->|holds| Memento
Loading
PatternDescription
chain_of_responsibilityapply a chain of successive handlers to try and process the data
cataloggeneral methods will call different specialized methods based on construction parameter
chaining_methodcontinue callback next object method
commandbundle a command and arguments to call later
interpreterdefine a grammar for a language and use it to interpret statements
iteratortraverse a container and access the container's elements
iterator (alt. impl.)traverse a container and access the container's elements
mediatoran object that knows how to connect other objects and act as a proxy
mementogenerate an opaque token that can be used to go back to a previous state
observerprovide a callback for notification of events/changes to data
publish_subscribea source syndicates events/data to 0+ registered listeners
registrykeep track of all subclasses of a given class
servantprovide common functionality to a group of classes without using inheritance
specificationbusiness rules can be recombined by chaining the business rules together using boolean logic
statelogic is organized into a discrete number of potential states and the next state that can be transitioned to
strategyselectable operations over the same data
templatean object imposes a structure but takes pluggable components
visitorinvoke a callback for all items of a collection

Design for Testability Patterns

PatternDescription
dependency_injection3 variants of dependency injection

Fundamental Patterns

PatternDescription
delegation_patternan object handles a request by delegating to a second object (the delegate)

Others

PatternDescription
blackboardarchitectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern
graph_searchgraphing algorithms - non gang of four pattern
hsmhierarchical state machine - non gang of four pattern

🚫 Anti-Patterns

This section lists some common design patterns that are not recommended in Python and explains why.

🧱 Singleton

Why not:

  • Python modules are already singletons — every module is imported only once.
  • Explicit singleton classes add unnecessary complexity.
  • Better alternatives: use module-level variables or dependency injection.

🌀 God Object

Why not:

  • Centralizes too much logic in a single class.
  • Makes code harder to test and maintain.
  • Better alternative: split functionality into smaller, cohesive classes.

🔁 Inheritance overuse

Why not:

  • Deep inheritance trees make code brittle.
  • Prefer composition and delegation.
  • “Favor composition over inheritance.”

Videos

Contributing

When an implementation is added or modified, please review the following guidelines:

Docstrings

Add module level description in form of a docstring with links to corresponding references or other useful information. Add "Examples in Python ecosystem" section if you know some. It shows how patterns could be applied to real-world problems. facade.py has a good example of detailed description, but sometimes the shorter one as in template.py would suffice.

Python 2 compatibility

To see Python 2 compatible versions of some patterns please check-out the legacy tag.

Update README

When everything else is done - update corresponding part of README.

Travis CI

Please run the following before submitting a patch:

  • If you have a bash-compatible shell, use ./lint.sh to run formatting, linting, type checking, and tests.

Development dependencies are pinned in Pipfile.lock. After changing Pipfile, activate a Python 3.10 virtual environment and run make lock to regenerate it.

Contributing via issue triage Open Source Helpers

You can triage issues and pull requests on CodeTriage.

About

A collection of design patterns/idioms in Python

Topics

Resources

Stars

42.9k stars

Watchers

1.6k watching

Forks

Releases

Used by

Contributors

Languages