0% found this document useful (0 votes)
784 views1 page

Decorator Hand Out

This document provides an overview of Python decorators, including how to define a basic decorator, use decorators with functions and classes, and more advanced topics like parameterized decorators and closures. Key points covered include: how to define a decorator that prints before and after a function is invoked, how *args and **kw allow functions to take arbitrary arguments, how @decorator syntax is syntactic sugar for assigning a decorated function, and how closures can be used to generate functions or decorate functions differently based on parameters.

Uploaded by

rodrigolgol
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
784 views1 page

Decorator Hand Out

This document provides an overview of Python decorators, including how to define a basic decorator, use decorators with functions and classes, and more advanced topics like parameterized decorators and closures. Key points covered include: how to define a decorator that prints before and after a function is invoked, how *args and **kw allow functions to take arbitrary arguments, how @decorator syntax is syntactic sugar for assigning a decorated function, and how closures can be used to generate functions or decorate functions differently based on parameters.

Uploaded by

rodrigolgol
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

Decorator Template

Python Decorators

>>> import functools


>>> def decorator(func_to_decorate):
...
@functools.wraps(func_to_decorate)
...
def wrapper(*args, **kw):
...
print "before invocation"
...
result = func_to_decorate(*args, **kw)
...
print "after invocation"
...
return result
...
return wrapper

Arguments
Variable arguments and variable keyword arguments are necessary for
functions that accept arbitrary parameters.
*args and **kw
>>>
...
>>>
[2,
>>>
>>>
[3,
>>>
[4,
>>>
[5,
>>>
[6,

def param_func(a, b='b', *args, **kw):


print [x for x in [a, b, args, kw]]
param_func(2, 'c', 'd', 'e,')
'c', ('d', 'e,'), {}]
args = ('f', 'g')
param_func(3, args)
('f', 'g'), (), {}]
param_func(4, *args) # tricksey!
'f', ('g',), {}]
param_func(5, 'x', *args)
'x', ('f', 'g'), {}]
param_func(6, **{'foo':'bar'})
'b', (), {'foo': 'bar'}]

The splat operator (* in a function invocation) is the same as


enumerating the values in the sequence.

Syntactic Sugar

>>> @decorator
... def foo():
...
print "hello"

and:
>>> def foo():
...
print "hello"
>>> foo = decorator(foo)

Invoking a decorated function:


>>> foo()
before invocation
hello
after invocation

>>> param_func(*args) # tricksey!


['f', 'g', (), {}]

and:
Parameterized decorators (need 2 closures)
>>> def limit(length):
...
def decorator(function):
...
@functools.wraps(function)
...
def wrapper(*args, **kw):
...
result = function(*args, **kw)
...
result = result[:length]
...
return result
...
return wrapper
...
return decorator

Closures
Closures are useful as function generators:
>>> def add_x(x):
...
def adder(y):
...
return x + y
...
return adder
>>>
>>>
>>>
15
>>>
17

Closures are also useful for decorators

Decorating classes
>>> class Cat(object):
...
def __init__(self, name):
...
self.name = name
...
...
@decorator
...
def talk(self, txt):
...
print '{0} said, "{1}"'.format(
...
self.name, txt)
...
...
@decorator2
...
def growl(self, txt):
...
print txt.upper()
>>> cat = Cat('Fred')
>>> cat.talk("Meow.")
before invocation
Fred said, "Meow."
after invocation
>>> cat.growl("GRRR.")
before func
GRRR.
after func

More Details
For an in depth explanation of the above check out my ebook, Guide to:
Learning Python Decorators. http://hairysun.com/books/decorators/

>>> @limit(5) # notice parens


... def echo(foo):
...
return foo

and:
>>> def echo(foo):
...
return foo
>>> echo = limit(5)(echo)
>>> echo('123456')
'12345'

Functions can decorate with @limit(1) or @limit(20)...

Python Decorators 1/1

>>> decorator2 = Decorator()


>>> @decorator2
... def nothing(): pass

The following are the same:

add_5 = add_x(5)
add_7 = add_x(7)
add_5(10)
add_7(10)

>>> class Decorator(object):


...
# in __init__ set up state
...
def __call__(self, function):
...
@functools.wraps(function)
...
def wrapper(*args, **kw):
...
print "before func"
...
result = function(*args, **kw)
...
print "after func"
...
return result
...
return wrapper

The following are the same:

The following are equivalent:

>>> param_func(args[0], args[1])


['f', 'g', (), {}]

Class instances as decorators

Matt Harrison 2012


http://hairysun.com/
Note that examples are illustrated as if they were done in a terminal.

You might also like