Decorators Pycon

https://www.youtube.com/watch?v=MjHpMCIvwsY

Slides and Code Snippets can be downloaded here

Snippet from Lecture:

import time

class CalledTooOftenError(Exception):
    pass

def once_per_minute(func):
    last_invoked = 0

    def wrapper(*args, **kwargs):
        nonlocal last_invoked

        elapsed_time = time.time() - last_invoked
        if elapsed_time < 60:
            raise CalledTooOftenError(f"Only {elapsed_time} has passed")
        last_invoked = time.time()

        return func(*args, **kwargs)

    return wrapper

if __name__ == '__main__':
    @once_per_minute
    def add(a, b):
        return a + b

    print(add(2, 2))
    print(add(3, 3))
def some_decorator(n):
    def middle(func): # func is function being decorated
        function_specific_local = 0

        def wrapper(*args, **kwargs):
            nonlocal function_specific_local

            function_specific_local += n
            return func(*args, **kwargs)
        return wrapper
    return middle
def my_function():
    ...
my_function = some_decorator(n=5)(my_function)

With a decorator:

@some_decorator(n=5)
def my_function()
  ...

key = (pickle.dumps(args), pickle.dump(kwargs))

Snippet from Lecture:

def fancy_repr(self):
    return f"I'm a {type(self).__name__}, with vars {vars(self)}"

def repr_and_birthday(c):
    c.__repr__ = fancy_repr

    def wrapper(*args, **kwargs):
        o = c(*args, **kwargs)
        o._created_at = time.time()
        return o
    return wrapper


if __name__ == '__main__':
    @repr_and_birthday
    class Foo():
        def __init__(self, x, y):
            self.x = x
            self.y = y

    f = Foo(10, [10, 20, 30])
    print(f)
    print(f._created_at)

Source:

from functools import partial

def power(base, exponent):
    return base ** exponent

square = partial(power, exponent=2)

assert square(2) == 4

https://www.youtube.com/watch?v=0LPuG825eAk

pdb notes

can set PYTHONBREAKPOINT=0 to disable all breakpoints

If you want to breakpoint when a crash happens in your program, you can use python3 -m pdb file.py, then hit c to continue. When a fatal error happens, you’ll be dropped into the debugger.

If the exception that causes the crash is caught/pretty-printed, you can use import pdb; pdb.post_mortem() to drop into the debugger in some higher stack frame.