Sometimes you can just write a function or method or class and be done with it. But sometimes you find that you need to wrap your functions or methods or classes in some sort of new behavior. And since you're a good programmer, you don't want to change every function in the same way over and over again. That's not DRY or a good use of your time! Well, when that happens, you just might need a decorator.
def outer():
number = 5
def inner():
print(number)
inner()
outer() # prints 5
def apply(func, x, y):
return func(x, y)
def add(a, b):
return a + b
print(apply(add, 5, 5)) # prints 10
def close():
x = 5
def inner():
print(x)
return inner
closure = close() # closure is actually a pointer to inner()
closure() # prints 5
def logme(func):
import logging # because we don't want to require users to import it
logging.basicConfig(level=logging.DEBUG)
def inner():
logging.debug("Called {}".format(func.__name__)
return func()
return inner
@logme
def say_hello():
print("Hello there!")
say_hello() # logs the call and then prints "Hello there!"