renamed package to pypattyrn

This commit is contained in:
tylerlaberge
2016-09-10 22:06:11 -04:00
parent bf8dd3830b
commit 3d5efea9b0
143 changed files with 16151 additions and 567 deletions

View File

View File

@@ -0,0 +1,33 @@
class Adapter(object):
"""
Adapter class as part of the Adapter design pattern.
- External Usage Documentation: U{https://github.com/tylerlaberge/PyPatterns/wiki/Structural-Pattern-Usage}
- External Adapter Pattern Documentation: U{https://en.wikipedia.org/wiki/Adapter_pattern}
"""
def __init__(self, adaptee, **adapted_methods):
"""
Initialize a new adapter instance.
@param adaptee: The object to adapt to a new interface.
@type adaptee: Object
@param adapted_methods: A dictionary of methods to adapt.
@type adapted_methods: dict
"""
self.__adaptee = adaptee
self.__dict__.update({k: v for k, v in adapted_methods.items() if callable(v) and
getattr(self.__adaptee, v.__name__, None)})
def __getattr__(self, attr):
"""
All non-adapted calls are passed to the adaptee.
@param attr: The attribute to get from the adaptee.
"""
return getattr(self.__adaptee, attr)
def original_dict(self):
"""
Get the adaptee's __dict__
"""
return self.__adaptee.__dict__

View File

@@ -0,0 +1,73 @@
class Composite(object):
"""
Composite class as part of the Composite pattern.
- External Usage Documentation: U{https://github.com/tylerlaberge/PyPatterns/wiki/Structural-Pattern-Usage}
- External Composite Pattern documentation: U{https://en.wikipedia.org/wiki/Composite_pattern}
"""
def __init__(self, interface):
"""
Initialize a new Composite instance.
@param interface: The interface the all child components must adhere to when added to this composite.
@type interface: class
"""
self.components = set()
self.interface = interface
def add_component(self, component):
"""
Add a component to this composite.
@param component: The component to add to this Composite
@raise AttributeError: If the component does not adhere to this Composites interface.
"""
valid = False
try:
if component.interface == self.interface:
valid = True
except AttributeError:
if self.interface in component.__class__.__mro__:
valid = True
finally:
if valid:
self.components.add(component)
else:
raise AttributeError('Component {0} does not follow this composites interface {1}'.format(
component.__class__, self.interface))
def remove_component(self, component):
"""
Remove a component from this composite.
@param component: The component to remove from this Composite.
"""
try:
self.components.remove(component)
except KeyError:
pass
def _delegate(self, func_name):
"""
Apply a function to all child components by function name.
@param func_name: The name of the function to call with all child components.
@type func_name: str
@raise AttributeError: If a child component does not have a callable function with the given name.
"""
for component in self.components:
attribute = getattr(component, func_name)
if callable(attribute):
attribute()
else:
raise AttributeError()
def __getattr__(self, item):
"""
Override getattr to delegate all function calls to children.
@param item: The function to call with this composites children components.
@type item: str
@return: A function that when called will call all child functions with the given function name.
"""
return lambda: self._delegate(item)

View File

@@ -0,0 +1,86 @@
from functools import partial
from abc import ABCMeta, abstractmethod
class Decorator(object, metaclass=ABCMeta):
"""
Base Decorator class that all decorator classes inherit from.
- External Usage Documentation: U{https://github.com/tylerlaberge/PyPatterns/wiki/Structural-Pattern-Usage}
- External Decorator Pattern documentation: U{https://en.wikipedia.org/wiki/Decorator_pattern}
"""
def __get__(self, instance, owner):
"""
Override __get__ in order to get the instance of a bound of method call.
"""
return partial(self.__call__, instance)
@abstractmethod
def __call__(self, *args, **kwargs):
"""
All decorators must implement a __call__ method.
"""
pass
class DecoratorSimple(Decorator, metaclass=ABCMeta):
"""
A Base Decorator class for decorators with no arguments.
- External Usage Documentation: U{https://github.com/tylerlaberge/PyPatterns/wiki/Structural-Pattern-Usage}
- External Decorator Pattern documentation: U{https://en.wikipedia.org/wiki/Decorator_pattern}
"""
def __init__(self, func):
"""
Initialize a new DecoratorSimple instance.
@param func: The function being decorated.
"""
self.func = func
class DecoratorComplex(Decorator, metaclass=ABCMeta):
"""
A Base Decorator class for decorators with arguments.
- External Usage Documentation: U{https://github.com/tylerlaberge/PyPatterns/wiki/Structural-Pattern-Usage}
- External Decorator Pattern documentation: U{https://en.wikipedia.org/wiki/Decorator_pattern}
"""
@abstractmethod
def __init__(self, *args, **kwargs):
"""
Initialize a new DecoratorComplex instance.
@param args: Args for the decorator.
@param kwargs: Keyword args for the decorator.
"""
pass
@abstractmethod
def __call__(self, func, *args, **kwargs):
"""
Concrete DecoratorComplex instances must override the __call__ method.
@param func: The function being decorated.
@param args: Arguments for the decorated function.
@param kwargs: Keyword arguments for the decorated function.
@return:
"""
pass
class CallWrapper(DecoratorSimple):
"""
A Decorator for wrapping DecoratorComplex __call__ methods.
- External Usage Documentation: U{https://github.com/tylerlaberge/PyPatterns/wiki/Structural-Pattern-Usage}
- External Decorator Pattern documentation: U{https://en.wikipedia.org/wiki/Decorator_pattern}
"""
def __call__(self, instance, func):
"""
Wrap a concrete DecoratorComplex __call__ method.
"""
def wrapped(*args, **kwargs):
return self.func(instance, func, *args, **kwargs)
return wrapped

View File

@@ -0,0 +1,48 @@
class FlyweightMeta(type):
"""
Flyweight meta class as part of the Flyweight design pattern.
- External Usage Documentation: U{https://github.com/tylerlaberge/PyPatterns/wiki/Structural-Pattern-Usage}
- External Flyweight Pattern documentation: U{https://en.wikipedia.org/wiki/Flyweight_pattern}
"""
def __new__(mcs, name, bases, attrs):
"""
Override class construction to add 'pool' attribute to classes dict.
@param name: The name of the class.
@param bases: Base classes of the class.
@param attrs: Attributes of the class.
@return: A new Class.
"""
attrs['pool'] = dict()
return super(FlyweightMeta, mcs).__new__(mcs, name, bases, attrs)
@staticmethod
def _serialize(cls, *args, **kwargs):
"""
Serialize arguments to a string representation.
"""
serialized_args = [str(arg) for arg in args]
serialized_kwargs = [str(kwargs), cls.__name__]
serialized_args.extend(serialized_kwargs)
return ''.join(serialized_args)
def __call__(cls, *args, **kwargs):
"""
Override call to use objects from a pool if identical parameters are used for object creation.
@param args: Arguments for class instantiation.
@param kwargs: Keyword arguments for class instantiation.
@return: A new instance of the class.
"""
key = FlyweightMeta._serialize(cls, *args, **kwargs)
pool = getattr(cls, 'pool', {})
instance = pool.get(key)
if not instance:
instance = super(FlyweightMeta, cls).__call__(*args, **kwargs)
pool[key] = instance
return instance