Advanced Python


Intro

Notebook that explores with examples advanced Python topics like closures, decorators, generators, etc.

Decorator

"a callable that takes a function as an argument and returns a replacement function"


In [7]:
import functools

In [10]:
# decorator function, which does basic logging
def log(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kw):
        print("Before decoration")
        result = fun(*args, **kw)
        print("After invocation")
        return result
    return wrapper

In [11]:
# base function
@log
def sum(a, b):
    return a + b

# equivalent to
#sum = log(sum)

In [12]:
sum(1,3)


Before decoration
After invocation
Out[12]:
4

Mutable Default Argument Value

What will the following code print?


In [18]:
def test(n, l=[]):
    for i in range(n):
        l.append(i)
    print(l)

In [19]:
test(3)
test(3, [1,2,3])
test(3)


[0, 1, 2]
[1, 2, 3, 0, 1, 2]
[0, 1, 2, 0, 1, 2]

In [24]:
# it can be noticed that the mutable argument changes
# are memorized in the method signature
import inspect
inspect.signature(test)


Out[24]:
<Signature (n, l=[0, 1, 2, 0, 1, 2])>

In [ ]: