This series of documents:

1. I finally figured out Python decorators (part 1)

2. I finally understand Python decorators (part 2)

3. I finally understand Python decorators (3)

4. I finally understand Python decorators (4)

When should decorators come into play?

Here’s the big question:

What can I do with decorators?

Decorators look cool and powerful, but it’s much clearer to show an actual example. There are 1000 possible scenarios used. But the classic usage:

  • Extend the behavior of a function through an external library (in cases where you cannot modify it).
  • Used for debugging (you do not want to modify it because it is temporary).
  • Reuse functions that can be added to multiple other functions through decorators.

You can use them to extend multiple functions in a chained fashion, as follows:

Def benchmark(func): """ decorator that prints the time the function takes to execute. """ import time def wrapper(*args, **kwargs): t = time.clock() res = func(*args, **kwargs) print("{0} {1}".format(func.__name__, Time.clock ()-t) return res return wrapper def logging(func): """ " (It's actually just printing out, but it's probably logging!) """ def wrapper(*args, **kwargs): res = func(*args, **kwargs) print("{0} {1} {2}".format(func.__name__, args, Kwargs)) return res return wrapper def counter(func): """ def wrapper(*args, **kwargs): wrapper.count = wrapper.count + 1 res = func(*args, **kwargs) print("{0} has been used: {1}x".format(func.__name__, wrapper.count)) return res wrapper.count = 0 return wrapper @counter @benchmark @logging def reverse_string(string): return str(reversed(string)) print(reverse_string("Able was I ere I saw Elba")) print(reverse_string("A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal: Panama!" #reverse_string ('Able was I ere I saw Elba',) {} #wrapper 0.0 #wrapper has been used: 1x #ablE was I ere I saw elbA #reverse_string ('A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal: Panama! ',) {} #wrapper 0.0 #wrapper has been used: 2x #! amanaP :lanac a ,noep a ,stah eros ,raj a ,hsac ,oloR a ,tur a ,mapS ,snip ,eperc a ,)lemac a ro( niaga gab ananab a ,gat a ,nat a ,gab ananab a ,gag a ,inoracam ,elacrep ,epins ,spam ,arutaroloc a ,shajar ,soreh ,atsap ,eonac a ,nalp a ,nam ACopy the code

Of course, the advantage of using decorators is that you can use them instantly on almost anything without rewriting them. Such as:

@counter @benchmark @logging def get_random_futurama_quote(): from urllib import urlopen result = urlopen("http://subfusion.net/cgi-bin/quote.pl?quote=futurama").read() try: value = result.split("<br><b><hr><br>")[1].split("<br><br><hr>")[0] return value.strip() except: return "No, I'm ... doesn't!" Print (get_random_futurama_quote()) print(get_random_futurama_quote()) #get_random_futurama_quote () {} #wrapper 0.02 #wrapper has been used: 1x #The laws of science be a harsh mistress. #get_random_futurama_quote () {} #wrapper 0.01 #wrapper has been used: 2x #Curse you, merciful Poseidon!Copy the code

This article started at BigYoung