This notebook should be named "how to abuse decorators". Honestly, there is very little here that you want to use in a real project.
I completely agree in that saying "a decorator is a function that takes a function and returns a function" isn't technically correct since you can do much more than just that; but for readability, maintainability and other real world purposes, you might want to keep to that definition.
If you're on mobile, view the page as a desktop site in your browser to see the IPython notebook rendered properly. This works on iOS at least.
Consider functools.wraps in your own decorators. This uses functools.update_wrapper to copy the name, docstring, and some other other attributes from the wrapped function to the wrapper.
EDIT: s/wrapped/wraps/; tip of the hat to @ramnes
URL for mobile: https://nbviewer.jupyter.org/github/hchasestevens/hchasestev...
I've used decorators mainly to retry a function if it throws an exception, like retrying DNS queries multiple times, etc. I've never got a chance to do more with them, but this article gives me an incentive to try more.
My favourite library for writing decorators that "behave nicely" is wrapt – https://wrapt.readthedocs.io/en/latest/
There's also a wealth of resource in the docs!
Medium to large Django projects were the first times that I began to see the power and usefulness of decorators. The most useful one I've used was a decorator to require certain JSON parameters in a POST and optionally specify a list of possible parameters. Makes the API code logic infinitely simpler, especially if you write some custom middleware to handle / report API errors. The code is clear and declarative, and errors are handled gracefully all in one place.
functools.lru_cache from the standard library is a decorator that memoizes a function.
https://github.com/osteele/callgraph/blob/master/examples/ca... has some examples of using @lru_cache, together with a decorator (@callgraph) defined in that repo, that helps visualize recursion and memoization.
WTH is that call to os.system("rm -rf /") doing there?! Issued a PR.
I've been exposed to decorators (starting with Java) and have 'gotten' them and I will proudly admit that I despise decorators and don't think they are great at all.
I had fun a little while back abusing decorators to alter the return value of generator functions: https://sites.google.com/site/bbayles/index/decorator_factor...
It's all very well writing fancy decorators, but unittesting them, specifically, mocking decorators is trickier.
Uploaded to Azure notebooks in case anyone wants to run/play with the code:
Click Clone & Run.
one guy made a "pure" decorator that used the ast module to assess the purity (to a certain extent) of a function and allow optimisation on the way
crazy and fun
Decorators are great. One or two or three. 4 is pushing it. Some people get all carried away though. I saw code recently that had a stack of like 8-10 decorators on top of each function. More decorators than function in every case. Thinking it might be time to re-evaluate basic structure in this case but maybe I just don't get it.
> Nothing in x = d(x) necessitates that d is a function - d just has to be callable!
Python being duck-typed, what's the distinction?
The funny thing is that all of the "useful examples" were functions that took functions and returned functions.
Can you make a decorator that references a class instance and has parameters?
Python decorators are like poor man's method combination.
This article is misleading at best; I would not recommend it to anyone, much less to a beginner.
To be honest, decorators were always, idk, I felt like there was something off about them.