Lecture Notes 17#
@pytest.mark.parametrize
def test_xxx():
...
def f(x):
return x**2
def g(func):
print("Calling function with x=2")
result = func(2)
print("Return value", result)
return result
g(f)
Calling function with x=2
Return value 4
4
function that takes another function as input
decorators#
function that take a function as input and returns a function as output
def id_decorator(func):
return func
g = id_decorator(f)
g(2)
4
f(2)
4
decorator that reports timing
import time
def f(x):
time.sleep(1)
return x**2
f(2)
4
t1 = time.time()
f(2)
t2 = time.time()
print("Time used in function", t2-t1)
Time used in function 1.0004487037658691
def time_me(func):
def wrapper(x):
t1 = time.time()
result = func(x)
t2 = time.time()
print("Time used in function", t2-t1)
return result
return wrapper
time_me(f)(2)
Time used in function 1.0001564025878906
4
f = time_me(f)
f(2)
Time used in function 1.00007963180542
4
@time_me
def f(x, a=1):
time.sleep(1)
return a*x**2
f(2)
Time used in function 1.0001444816589355
4
f(2, a=.1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[17], line 1
----> 1 f(2, a=.1)
TypeError: time_me.<locals>.wrapper() got an unexpected keyword argument 'a'
For general arguments: args/kwargs
def wrapper(*args, **kwargs):
print(args)
print(kwargs)
wrapper()
()
{}
wrapper(1, 2)
(1, 2)
{}
wrapper(1, 2, c=3)
(1, 2)
{'c': 3}
def time_me(func):
def wrapper(*args, **kwargs):
t1 = time.time()
result = func(*args, **kwargs)
t2 = time.time()
print("Time used in function", t2-t1)
return result
return wrapper
@time_me
def f(x, a=1):
time.sleep(1)
return a*x**2
f(2)
Time used in function 1.0001630783081055
4
f(2, a=0.1)
Time used in function 1.0001263618469238
0.4
decorator for debugging
def trace(func):
def wrapper(*args, **kwargs):
print(f"{func.__name__} called with arguments {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returns {result}")
return result
return wrapper
def time_me(func):
def wrapper(*args, **kwargs):
t1 = time.time()
result = func(*args, **kwargs)
t2 = time.time()
print(f"Time used in {func.__name__}", t2-t1)
return result
return wrapper
@time_me
@trace
def my_square(x, a=1):
time.sleep(1)
return a*x**2
my_square(2, a=0.1)
my_square called with arguments (2,), {'a': 0.1}
my_square returns 0.4
Time used in wrapper 1.000516653060913
0.4
from functools import wraps
def trace(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"{func.__name__} called with arguments {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returns {result}")
return result
return wrapper
def time_me(func):
@wraps(func)
def wrapper(*args, **kwargs):
t1 = time.time()
result = func(*args, **kwargs)
t2 = time.time()
print(f"Time used in {func.__name__}", t2-t1)
return result
return wrapper
@time_me
@trace
def my_square(x, a=1):
time.sleep(1)
return a*x**2
my_square(2, a=0.1)
my_square called with arguments (2,), {'a': 0.1}
my_square returns 0.4
Time used in my_square 1.0028369426727295
0.4
import functools
@functools.cache
@time_me
def my_square(x, a=1):
time.sleep(1)
return a*x**2
my_square(3, a=.1)
Time used in my_square 1.000098466873169
0.9
my_square(4, a=1)
Time used in my_square 1.0000760555267334
16
my_square(3, a=.1)
0.9
my_square(4, a=1)
16
my_square(4, a=2)
Time used in my_square 1.0001099109649658
32