PyPattyrn
A simple library for implementing common design patterns.
Install / Use
/learn @tylerlaberge/PyPattyrnREADME
NOTE: This repository is not maintained and should not be used. Most of the design patterns implemented in this repository are not really needed when writing idomatic Python.
PyPattyrn
from pypattyrn.creational.singleton import Singleton
class DummyClass(object, metaclass=Singleton): # DummyClass is now a Singleton!
...
PyPattyrn is a python package aiming to make it easier and faster to implement design patterns into your own projects.
Design patterns by nature cannot be directly translated into code as they are just a description of how to solve a particular problem. However, many of the common design patterns have boilerplate code that is common throughout all implementations of the pattern. This package captures that common code and makes it easy to use so that you dont have to write it yourself in all your projects.
Contents
Installation
pip install pypattyrn
or
git clone https://github.com/tylerlaberge/PyPattyrn.git
cd PyPattyrn
python setup.py install
Examples
Behavioral Patterns
Patterns which deal with communication between objects.
Chain of Responsibility Pattern
Pass a request along a chain of objects until the request is handled.
from pypattyrn.behavioral.chain import Chain, ChainLink
class ConcreteChainLinkThree(ChainLink): # This object is a ChainLink
def handle(self, request): # Implement the handle method.
if request == 'handle_three':
return "Handled in chain link three"
else:
return self.successor_handle(request) # If this ChainLink can't handle the request,
# ask its successor to handle it.
# (Has no successor so will raise AttributeError)
# (This exception is caught and will call a Chains fail method)
class ConcreteChainLinkTwo(ChainLink): # This object is a ChainLink
def __init__(self): # Override init to set a successor on initialization.
super().__init__() # first call ChainLinks init
self.set_successor(ConcreteChainLinkThree()) # Set the successor of this chain link
# to a ConcreteChainLinkThree instance.
def handle(self, request): # Implement the handle method.
if request == 'handle_two':
return "Handled in chain link two"
else:
return self.successor_handle(request) # If this ChainLink can't handle a request
# ask its successor to handle it
# (the ConcreteChainLinkThree instance).
class ConcreteChainLinkOne(ChainLink): # This object is a ChainLink
def __init__(self):
super().__init__()
self.set_successor(ConcreteChainLinkTwo()) # Set the successor of this ChainLink
# to a ConcreteChainLinkTwo instance.
def handle(self, request): # Implement the handle method.
if request == 'handle_one':
return "Handled in chain link one"
else:
return self.successor_handle(request) # If this ChainLink can't handle a request
# ask its successor to handle it
# (the ConcreteChainLinkTwo instance).
class ConcreteChain(Chain): # This object is a Chain
def __init__(self): # Override init to initialize a Chain with the starting chain link.
super().__init__(ConcreteChainLinkOne()) # Initialize this Chain with a start chain link.
# (a ConcreteChainLinkOne instance)
def fail(self): # Implement the fail method, this is called if no chain links could handle a request.
return 'Fail'
chain = ConcreteChain()
assert "Handled in chain link one" == chain.handle("handle_one")
assert "Handled in chain link two" == chain.handle("handle_two")
assert "Handled in chain link three" == chain.handle("handle_three")
assert "Fail" == chain.handle('handle_four')
Command Pattern
Encapsulate information for performing an action into an object.
from pypattyrn.behavioral.command import Receiver, Command, Invoker
class Thermostat(Receiver): # This object is a Receiver.
# Contains methods for commands to use.
def raise_temp(self, amount):
return "Temperature raised by {0} degrees".format(amount)
def lower_temp(self, amount):
return "Temperature lowered by {0} degrees".format(amount)
class RaiseTempCommand(Command): # This object is a Command.
def __init__(self, receiver, amount=5): # Override init to include a temperature amount argument.
super().__init__(receiver)
self.amount = amount
def execute(self): # Implement the execute method.
return self._receiver.action('raise_temp', self.amount) # Call on the Receiver's action method with
# the name of the method to call and args.
# (Raises the temperature by 5 degrees.)
def unexecute(self): # Implement the unexecute method.
return self._receiver.action('lower_temp', self.amount) # Calls on the Receiver to lower
# the temperature by 5 degrees.
class LowerTempCommand(Command): # This object is a Command.
def __init__(self, receiver, amount=5):
super().__init__(receiver)
self.amount = amount
def execute(self):
return self._receiver.action('lower_temp', self.amount) # Call on the receiver to lower the
# temperature by 5 degrees.
def unexecute(self):
return self._receiver.action('raise_temp', self.amount) # Call on the receiver to raise the
# temperature by 5 degrees.
class Worker(Invoker): # This object is the Invoker
def __init__(self): # Override init to initialize an Invoker with Commands to accept.
super().__init__([LowerTempCommand, RaiseTempCommand]) # Initialize the Invoker with the
# LowerTempCommand and RaiseTempCommand classes.
thermostat = Thermostat() # Create a Receiver.
worker = Worker() # Create an Invoker.
assert "Temperature lowered by 5 degrees" == worker.execute(LowerTempCommand(thermostat)) # Have the Invoker execute a LowerTempCommand
# which uses the thermostat Receiver.
assert "Temperature raised by 5 degrees" == worker.execute(RaiseTempCommand(thermostat)) # Have the Invoker execute a RaiseTempCommand
# which uses the thermostat Receiver.
assert "Temperature lowered by 5 degrees" == worker.undo() # Undo the previous command (Calls the RaiseTempCommand unexecute method.)
Iterator Pattern
A way of sequentially accessing elements in a collection.
from pypattyrn.behavioral.iterator import Iterable, Iterator
class Counter(Iterable): # This object is an Iterable
def __init__(self, max):
self.count = 0
self.max = max
def __next__(self): # Implement the __next__ method.
self.count += 1 # Increment the count
if self.count > self.max:
raise StopIteration() # make sure to raise StopIteration at the appropriate time.
else:
return self.count - 1 # Return the count
class CounterIterator(Iterator): # This object is an Iterator
def __init__(self): # Override init to initialize a
