What is the difference between “Python decorators” and the “decorator pattern”?
When should I use Python decorators, and when should I use the decorator pattern?
I'm looking for examples of Python decorators and the decorator pattern accomplishing same.
@AcceptedAnswer
I know that Jakob Bowyer's answer is valid. Yet it's Srikar's answer that made me understand why.
After Srikar's answer, and studying the given resources, I've written this example, so I can visualize and understand Python decorators and the decorator pattern.
I must disagree with Srikar's "Python decorators are not an implementation of the decorator pattern". After what I've learned, I'm strongly convinced that Python decorators are an implementation of the decorator pattern. Just not in the classic way.
Also, I need to add that, despite the fact that Srikar said "Python decorators add functionality to functions and methods at definition time", you can easily use Python decorators at run time.
Yet, I still mark Srikar's answer as accepted, because it helped me understand the implementation of the decorator pattern in Python.
"""
Testing Python decorators against the decorator pattern
"""
def function(string):
return string
def decorator(wrapped):
def wrap(string):
# Assume that this is something useful
return wrapped(string.upper())
return wrap
def method_decorator(wrapped):
def wrap(instance, string):
# Assume that this is something useful
return wrapped(instance, string.upper())
return wrap
@decorator
def decorated_function(string):
print('! '.join(string.split(' ')))
class Class(object):
def __init__(self):
pass
def something_useful(self, string):
return string
class Decorator(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def something_useful(self, string):
string = '! '.join(string.split(' '))
return self.wrapped().something_useful(string)
@method_decorator
def decorated_and_useful(self,string):
return self.something_useful(string)
if __name__ == '__main__':
string = 'Lorem ipsum dolor sit amet.'
print(function(string)) # Plain function
print(decorator(function)(string)) # Python decorator at run time
print(decorated_function(string)) # Python decorator at definition time
a = Class()
print(a.something_useful(string)) # Plain method
b = Decorator(Class)
print(b.something_useful(string)) # Decorator pattern
print(b.decorated_and_useful(string)) # Python decorator decorated the decorator pattern