Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Decorators: A Powerful Weapon in Your Python Ar...

PyCon 2014
April 11, 2014
1.6k

Decorators: A Powerful Weapon in Your Python Arsenal by Colton Myers

PyCon 2014

April 11, 2014
Tweet

Transcript

  1. The Plan • What is a decorator? • How are

    decorators constructed? • How do they work? • The “right” way to make decorators • Examples
  2. Decorators wrap functions • Add functionality • Modify behavior •

    Perform setup/teardown • Diagnostics (timing, etc)
  3. def make_printer(word): def inner(): print(word) return inner ! ! p

    = make_printer(‘such wow!’) p() #prints “such wow!”
  4. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner @shout def myfunc(): print(‘such wow!’)
  5. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner @shout def myfunc(): print(‘such wow!’)
  6. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner @shout def myfunc(): print(‘such wow!’)
  7. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner @shout def myfunc(): print(‘such wow!’)
  8. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  9. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  10. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  11. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  12. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  13. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  14. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  15. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  16. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  17. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  18. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  19. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  20. def shout(wrapped): def inner(*args, **kwargs): print(‘BEFORE!’) ret = wrapped(*args, **kwargs)

    print(‘AFTER!’) return ret inner.__name__ = wrapped.__name__ return inner myfunc = shout(myfunc) def myfunc(): print(‘such wow!’)
  21. import wrapt ! @wrapt.decorator def pass_through(wrapped, instance, args, kwargs): return

    wrapped(*args, **kwargs) ! @pass_through def function(): pass
  22. import wrapt ! @wrapt.decorator def pass_through(wrapped, instance, args, kwargs): return

    wrapped(*args, **kwargs) ! @pass_through def function(): pass
  23. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec @skipIf(True, ‘I hate doge’) def myfunc(): print(‘very print’)
  24. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  25. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  26. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  27. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  28. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  29. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  30. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  31. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec myfunc = skipIf(True, ‘I hate doge’)(myfunc) def myfunc(): print(‘very print’)
  32. def skipIf(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not

    conditional: return wrapped(*args, **kwargs) else #skipping print(message) return inner return dec @skipIf(True, ‘I hate doge’) def myfunc(): print(‘very print’)
  33. import wrapt ! def with_arguments(myarg1, myarg2): @wrapt.decorator def wrapper(wrapped, instance,

    args, kwargs): return wrapped(*args, **kwargs) return wrapper ! @with_arguments(1, 2) def function(): pass
  34. import wrapt ! def with_arguments(myarg1, myarg2): @wrapt.decorator def wrapper(wrapped, instance,

    args, kwargs): return wrapped(*args, **kwargs) return wrapper ! @with_arguments(1, 2) def function(): pass
  35. import wrapt ! def with_arguments(myarg1, myarg2): @wrapt.decorator def wrapper(wrapped, instance,

    args, kwargs): return wrapped(*args, **kwargs) return wrapper ! @with_arguments(1, 2) def function(): pass
  36. def count(wrapped): def inner(*args, **kwargs): inner.counter += 1 return wrapped(*args,

    **kwargs) inner.counter = 0 return inner @count def myfunc(): pass
  37. def count(wrapped): def inner(*args, **kwargs): inner.counter += 1 return wrapped(*args,

    **kwargs) inner.counter = 0 return inner @count def myfunc(): pass
  38. import time def timer(wrapped): def inner(*args, **kwargs): t = time.time()

    ret = wrapped(*args, **kwargs) print(time.time()-t) return ret return inner @timer def myfunc(): print(‘so example!’)
  39. import time def timer(wrapped): def inner(*args, **kwargs): t = time.time()

    ret = wrapped(*args, **kwargs) print(time.time()-t) return ret return inner @timer def myfunc(): print(‘so example!’)