python-patterns

A collection of design patterns/idioms in Python

42,896 stars Python Markdown Skills API Spec #design-patterns#idioms#python
AI Prompts & Specs

Repository: faif/python-patterns


Stars: 42711

README.md

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.

mermaid
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

| Pattern | Description |
|:-------:| ----------- |
| abstract_factory | use a generic function with specific factories |
| borg | a singleton with shared-state among instances |
| builder | instead of using multiple constructors, builder object receives parameters and returns constructed objects |
| factory | delegate a specialized function/method to create instances |
| lazy_evaluation | lazily-evaluated property pattern in Python |
| pool | preinstantiate and maintain a group of instances of the same type |
| prototype | use 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.

mermaid
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

| Pattern | Description |
|:-------:| ----------- |
| 3-tier | data<->business logic<->presentation separation (strict relationships) |
| adapter | adapt one interface to another using a white-list |
| bridge | a client-provider middleman to soften interface changes |
| composite | lets clients treat individual objects and compositions uniformly |
| decorator | wrap functionality with other functionality in order to affect outputs |
| facade | use one class as an API to a number of others |
| flyweight | transparently reuse existing instances of objects with similar/identical state |
| front_controller | single handler requests coming to the application |
| mvc | model<->view<->controller (non-strict relationships) |
| proxy | an object funnels operations to something else |

Behavioral Patterns

Patterns concerned with communication and responsibility between objects.

mermaid
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

| Pattern | Description |
|:-------:| ----------- |
| chain_of_responsibility | apply a chain of successive handlers to try and process the data |
| catalog | general methods will call different specialized methods based on construction parameter |
| chaining_method | continue callback next object method |
| command | bundle a command and arguments to call later |
| interpreter | define a grammar for a language and use it to interpret statements |
| iterator | traverse a container and access the container's elements |
| iterator (alt. impl.)| traverse a container and access the container's elements |
| mediator | an object that knows how to connect other objects and act as a proxy |
| memento | generate an opaque token that can be used to go back to a previous state |
| observer | provide a callback for notification of events/changes to data |
| publish_subscribe | a source syndicates events/data to 0+ registered listeners |
| registry | keep track of all subclasses of a given class |
| servant | provide common functionality to a group of classes without using inheritance |
| specification | business rules can be recombined by chaining the business rules together using boolean logic |
| state | logic is organized into a discrete number of potential states and the next state that can be transitioned to |
| strategy | selectable operations over the same data |
| template | an object imposes a structure but takes pluggable components |
| visitor | invoke a callback for all items of a collection |

Design for Testability Patterns

| Pattern | Description |
|:-------:| ----------- |
| dependency_injection | 3 variants of dependency injection |

Fundamental Patterns

| Pattern | Description |
|:-------:| ----------- |
| delegation_pattern | an object handles a request by delegating to a second object (the delegate) |

Others

| Pattern | Description |
|:-------:| ----------- |
| blackboard | architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern |
| graph_search | graphing algorithms - non gang of four pattern |
| hsm | hierarchical 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

* Design Patterns in Python by Peter Ullrich
* Sebastian BuczyΕ„ski - Why you don't need design patterns in Python?
* You Don't Need That!
* Pluggable Libs Through Design Patterns

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:
- black . This lints your code.
- Either tox or tox -e ci37 for unit tests.
- If you have a bash compatible shell, use ./lint.sh.

Contributing via issue triage ![Open Source Helpers](https://www.codetriage.com/faif/python-patterns)


You can triage issues and pull requests on CodeTriage.