Talk Dont Use Design Patterns Python
Talk Dont Use Design Patterns Python
PATTERNS IN PYTHON?
Pycon PL 2017
EVERYTHING STARTS WITH A STORY...
STORY OF A PYTHON
Zen DEVELOPER
of Python!
TDD
Readability
FOR THE
first!
WIN!!!
return cls._instance
SINGLETON - __NEW__
class Singleton:
_instance = None
return cls._instance
one_instance = Singleton()
another_instance = Singleton()
@classmethod
def get_instance(cls):
if not cls._instance:
cls._instance = cls()
return cls._instance
one_instance = Singleton.get_instance()
another_instance = Singleton()
singleton = Singleton()
# another modules
from my_code import singleton
SINGLETONS IN PYTHON?
MODULES!
Exactly one instance living in sys.modules
Get an instance easily import module
Recreate using importlib.reload(module) #Py3
SINGLETON - CONCLUSION
Using a module may be better than creating class
SPEAKING OF MODULES - FAÇADE
SPEAKING OF MODULES - FAÇADE
SPEAKING OF MODULES - FAÇADE
SPEAKING OF MODULES - FAÇADE
SPEAKING OF MODULES - FAÇADE
Instead one big mess...
SPEAKING OF MODULES - FAÇADE
...you get few smaller ones.
FAÇADE - CLASS
class AdvertisementsFacade:
@classmethod
def get_advert_for_single_post(post):
pass
@classmethod
def get_adverts_for_main_page(count):
pass
FAÇADE - MODULE
def get_advert_for_single_post(post):
pass
def get_adverts_for_main_page(count):
pass
import advertisements
adverts = advertisements.get_adverts_for_main_page(count=3)
FAÇADE - CONCLUSION
Helpful to organize code, no need for a class
COMMAND
Object oriented callback
class Client:
def foo(self):
some_obj = SomeClass()
command = Command(some_obj)
self.menu_item.set_command(command)
def execute(discount_rate):
self.object.notify_users_about_discount(discount_rate)
COMMAND - FUNCTION
def command(discount_rate):
some_obj.notify_users_about_discount()
command = functools.partial(
some_obj.notify_users_about_discount, discount_rate=0.5
)
command()
# equals to
some_obj.notify_users_about_discount(discount_rate=0.5)
COMMAND - CONCLUSION
Fair solution for GUI applications
Usually a function does just fine
VISITOR PATTERN
Let's say we have a complicated, nested data structure to
parse.
VISITOR - EXAMPLE
Abstract Syntax Trees (ASTs) - used in Pylint
import time
def ten_seconds_ago():
now = time.time()
return now - 10
VISITOR IMPLEMENTATION - JAVA
public class ASTVisitor {
public void visit(ImportNode import) {}
@singledispatch
def visit(node):
type_name = type(node).__name__
raise AttributeError(f'No handler found for {type_name}')
from ast_nodes import Assign, FunctionDef
@visit.register(Assign)
def visit(node):
pass
@visit.register(FunctionDef)
def visit(node):
pass
PYTHON WITH @SINGLEDISPATCH - FINAL
REMARKS
decorated_object = Decorator(original_object)
decorated_object.foo()
def get_number(self):
pass
class Decorator:
def __init__(self, decorated_obj):
self.decorated_obj = decorated_obj
def get_text(self):
original_text = self.decorated_obj.get_text()
return f'<b>{original_text}</b>'
def get_number(self):
return self.decorated_obj.get_number()
def __init__(self):
self.some_attr = 2
example = ClsVsObject()
example.__dict__['some_attr'] # 2, == example.some_attr
example.__class__.__dict__['some_attr'] # 1 == ClsVsObject.some_attr
example.some_attr # 2
ClsVsObject.some_attr # 1
DECORATOR - IMPLEMENTATION
class Decorator:
def __init__(self, decorated_obj):
self.decorated_obj = decorated_obj
def get_text(self):
original_text = self.decorated_obj.get_text()
return f'{original_text}'
Questions?