Python Design Patterns, Part One

Design Patterns

Decorator Pattern

  • Enhancing the response of a component that is sending data to a second component
  • Supporting multiple optional behaviors
import time


def log_calls(func):
# Defines a new function
def wrapper(*args, **kwargs):
now = time.time()
print(f"Calling {func.__name__} with {args} and {kwargs}")
return_value = func(*args, **kwargs)
print(f"Executed {func.__name__} in {time.time() - now}ms")
return return_value
# Return the new function
return wrapper


@log_calls
def test1(a, b, c):
print(f"\t test1 called")


@log_calls
def test2(a, b):
print(f"\t test2 called")


@log_calls
def test3(a, b):
print(f"\t test1 called")
time.sleep(1)


test1(1, 2, 3)
test2(4, b=5)
test3(6, 7)

Observer Pattern

class Inventory:
def __init__(self):
self.observers = []
self._product = None
self._quantity = 0

def attach(self, observer):
self.observers.append(observer)

@property
def product(self):
return self._product

@product.setter
def product(self, value):
self._product = value
self._update_observers()

@property
def quantity(self):
return self._quantity

@quantity.setter
def quantity(self, value):
self._quantity = value
self._update_observers()

def _update_observers(self):
for observer in self.observers:
observer()


class ConsoleObserver:
def __init__(self, inventory):
self.inventory = inventory

def __call__(self):
if self.inventory.quantity > 4:
print(f"{self.inventory.product} has {self.inventory.quantity}, overload warning!")
print(self.inventory.product)
print(self.inventory.quantity)

Strategy Pattern

State Pattern

Singleton Pattern

class OneOnly:
_singleton = None

def __new__(cls, *args, **kwargs):
if not cls._singleton:
cls._singleton = super(OneOnly, cls).__new__(cls, *args, **kwargs)
return cls._singleton

Template Pattern

  • Connect to database
  • Construct a query
  • Issue the query
  • Parse the result
  • Output the data
class QueryTemplate:
def connect(self):
pass
def construct_query(self):
pass
def do_query(self):
pass
def parse_results(self):
pass
def output_results(self):
pass
def process_query(self):
self.connect()
self.construct_query()
self.do_query()
self.parse_results()
self.output_results()
class NewUserQuery(QueryTemplate):
def construct_query(self):
self.query = "select * from Users where new='true'"

--

--

--

Senior Cloud Engineer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Daily links of Fernand0 — Enlaces diarios de Fernand0 — Issue #366

Azure Cosmos DB: Build a MongoDB API console app with Golang and the Azure portal

Switch-case indentation problem in programming

String operations using slice, substring and substr

What’s next for MobileFFmpeg?

Introduction to Application Framework

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Tony

Tony

Senior Cloud Engineer

More from Medium

Pytest in Python

Python Checkbutton| Tkinter Python main Checkbutton Kaise Create Kare

How to Optimise Python Performance

Python string replacement | string. replace() method