In [1]:
from IPython.display import Image
def decorators(f):
return f
In [2]:
@decorators
def holidays():
print("PyATL Decmember 2014")
In [3]:
Image("resources/present.jpg")
Out[3]:
In [4]:
Image("resources/wrapped_presents_2.jpg")
Out[4]:
In [5]:
my_func = dir
funcs = [enumerate, list, int]
map(float, [1, 2, 3])
def returns_help():
return help
In [6]:
def outer(x=4):
def inner(y=0):
return x+y
return inner
o = outer()
print(o())
print(o.__closure__) #func_closure in Py2
In [7]:
def awesome(f):
return f
@awesome
def my_func():
pass
my_func = awesome(my_func)
In [8]:
from time import time
from functools import wraps
def timeit(f):
@wraps(f)
def timer(*args, **kwargs):
start = time()
res = f(*args, **kwargs)
print(time() - start)
return res
return timer
@timeit
def hello():
print("Hello!")
hello()
In [9]:
def make_awesome(f):
f.awesome = True
return f
@make_awesome
def thing():
return "Thing()"
assert hasattr(thing, "awesome")
In [10]:
def brittle(f):
def wrapper(arg1, arg2, kwarg1=None, kwarg2=None):
return f(arg1, arg2, kwarg1, kwarg2)
return wrapper
In [11]:
def flexible(f):
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper
In [12]:
@flexible
def dinner(food, beer): # actually becomes wrapper
print("Eating", food, "and drinking", beer)
dinner("Bratzel", "Azazel")
print(dinner.__name__)
In [13]:
def loggit(f):
def logger(*args, **kw):
print("Calling {}.".format(f.__name__))
return f(*args, **kw)
logger.__name__ = f.__name__
logger.__doc__ = f.__doc__
logger.__dict__.update(f.__dict__)
return logger
In [14]:
from functools import wraps
def loggit(f):
@wraps(f)
def logger(*args, **kwargs):
print("Calling {}.".format(f.__name__))
return f(*args, **kwargs)
return logger
@loggit
def random():
"""Chosen by fair dice roll."""
return 4
print(random.__name__)
print(random.__doc__)
In [15]:
def before(phrase="Setting up"):
def actual_deco(f):
@wraps(f)
def wrapper(*args, **kwargs):
print(phrase)
return f(*args, **kwargs)
return wrapper
return actual_deco
In [16]:
@before(phrase="much setup!")
def does_nothing():
print("I did nothing.")
@before() # parens must be present
def add_two(x):
return x + 2
In [17]:
from functools import partial
def before(f=None, phrase="Setting up"):
if f is None:
return partial(before, phrase=phrase)
@wraps(f)
def wrapper(*args, **kwargs):
print(phrase)
return f(*args, **kwargs)
return wrapper
In [18]:
@before(phrase="much setup!")
def does_nothing():
print("I did nothing.")
@before # parens not required
def add_two(x):
return x + 2
In [19]:
def optional_kwargs(deco):
@wraps(deco)
def wrapper(f=None, **kwargs):
if f is None:
return partial(wrapper, **kwargs)
return deco(f, **kwargs)
return wrapper
In [20]:
@optional_kwargs
def before(f, phrase="Setting up"):
@wraps(f)
def wrapper(*args, **kwargs):
print(phrase)
return f(*args, **kwargs)
return wrapper
@before
def add_two(x):
return x + 2
add_two(4)
Out[20]:
In [21]:
from functools import total_ordering
@total_ordering
class Frob:
def __init__(self, bar):
self.bar = bar
self.baz = bar * 2
def __eq__(self, other):
(self.bar + self.baz) == (other.bar + other.baz)
def __gt__(self, other):
(self.bar + self.baz) > (other.bar + other.baz)
Frob(4) < Frob(2)
Out[21]:
In [22]:
from functools import update_wrapper
class wrapperobj:
def __init__(self, f):
update_wrapper(self, f)
self.f = f
def __call__(self, *args, **kwargs):
return self.f(*args, **kwargs)
@wrapperobj
def random():
return 4
print(random())
In [23]:
class singlewrapper:
def __call__(self, f):
@wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper
wrapper = singlewrapper()
@wrapper
def random():
return 4
print(random())
In [24]:
class Foo:
@loggit
def frob(self, n=2):
print(" ".join(["Frob"] * n))
Foo().frob(n=2)
In [25]:
class Foo:
@wrapperobj
def frob(self, n=1):
print(" ".join(["Frob"] * n))
Foo().frob
Out[25]:
In [26]:
class methodwrapper:
def __init__(self, method):
self.method = method
def __get__(self, instance, cls):
if instance is None:
return self.method
return partial(self.method, instance)
In [27]:
class Foo:
@methodwrapper
def frob(self, n=1):
print(" ".join(["Frob"] * n))
Foo().frob(n=2)
In [28]:
Image("resources/Star-Wars-Nesting-Dolls-02.jpg")
Out[28]:
In [29]:
@wrapperobj
@before(phrase="This was chosen by a fair dice roll.")
@make_awesome
def random(*args, **kwargs):
return 4
print(hasattr(random, 'awesome'))
print(random.__name__)
In [30]:
import inspect
print(inspect.getargspec(dinner))
print(inspect.getsource(dinner))
In [31]:
print(random.__wrapped__.__name__)
print(inspect.getsource(inspect.unwrap(random)))
In [32]:
print(inspect.getsource(Foo.frob))
In [33]:
Image("resources/ian-malcolm.jpg")
Out[33]:
In [34]:
from itertools import repeat
@repeat
def frob():
return 4
print(next(frob))