Decorators and Generators are one of the most appealing features of Pythons. Colton Myers gave a talk at PyCon 2014 on decorators. Following is summary of that talk What is a Decorator? This is what a decorator looks like
Decorators and Generators are one of the most appealing features of Pythons. Colton Myers gave a talk at PyCon 2014 on decorators. Following is summary of that talk What is a Decorator? This is what a decorator looks like
Source: PyCon 2014 on decorators.
This is what a decorator looks like
@my_decorator
def my_awesome_function():
pass
# this is called closure
def make_printer(word):
def inner():
print(word)
return inner
p = make_printer('such wow')
p()
# this is no-op decorator
def my_decorator(wrapped):
def inner(*args, **kwargs):
return wrapped(*args, **kwargs)
return inner
# decorator is called syntactic sugar
@my_decorator
def myfun():
pass
def shout(wrapped):
def inner(*args, **kwargs):
print("BEFORE")
ret = wrapped(*args, **kwargs)
print("AFTER")
return ret
return inner
@shout
def myfunc():
print("such wow!")
# Output that you will see after calling myfunc is
# >>> myfunc()
# BEFORE
# such wow!
# AFTER
# >>>
Good decorators are versatile
*args
and **kwargs
together take any number of positional and/or keyword arguments
*args
as a list**kwargs
as dictionarymyfunc.__name__
it returns inner
inner.__name__ == wrapped.__name__
before return inner
import wrapt
@wrapt.decorator
def pass_through(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
@pass_through
def function():
pass
instance
variable this allows you to wrap classes and objectsHere is an example
def skipIf(conditional, message):
def dec(wrapped):
def inner(*args, **kwargs):
if not conditional:
return wrapped(*args, **kwargs)
else:
print(message)
return inner
return dec
@skipIf(True, 'I hate doge')
def myfunc():
print("very print")
# Output
# >>> myfunc()
# I hate doge
import wrapt
def with_arguments(myarg1, myarg2):
@wrapy.decorator
def wrapped(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
return wrapped
@with_arguments(1, 2)
def function():
pass
Following is an example of how to count number of times a function has been called
def count(wrapped):
def inner(*args, **kwargs):
inner.counter += 1
return wrapped(*args, **kwargs)
inner.counter = 0
return inner
@count
def myfunc():
pass
counter
variableimport time
def timer(wrapped):
def inner(*args, **kwargs):
t = time.time()
ret = wrapped(*args, **kwargs)
print(time.time() - t)
return ret
return inner
@timer
def myfunc():
print("so example!")