3 ms·
Decorators are very easy to understand. They take the arguments going into the decorated function, do work, then call the decorated function, receive the return
by seibelj 11y ago
Decorators are very easy to understand. They take the arguments going into the decorated function, do work, then call the decorated function, receive the return values, and then take the returned values and do more work.
This could mean validating function inputs, changing inputs, raising exceptions, doing cleanup, etc. I use them liberally for web service endpoints to validate security, data integrity, etc.
- chucksmash 11y ago> Decorators are very easy to understand I use them every day but I think this view only seems true when one is looking back in hindsight. Even fundamental ideas like assignment and the scoping of variables can be difficult for newbies. To really grok decorators (i.e. not just to use them as prescribed by the Django/Flask/whatever docs but to take the next step and create your own), one needs to be comfortable with the idea of first class functions - not a first day topic, at any rate.
- philh 11y agoI don't care for that explanation, because they don't have to call the original function. (E.g. an @skip('not yet implemented') test decorator.) Or they could call it multiple times. The post-decoration function doesn't even need to be a function[1]. And that doesn't touch on decorated classes, either. I find them easiest to understand using the source-rewriting explanation: @foo def bar(...): ... is the same as def bar(...): ... bar = foo(bar) Classes can be decorated in the same way. This also explains why decorators taking arguments work how they do: because @foo(...) turns into bar = foo(...)(bar) and thus foo needs to return a decorator, not be a decorator. (Where a decorator can be thought of as "any function that accepts a single argument", or as "any function which happens to be useful as a decorator", or whatever.) But explaining them like this doesn't make it obvious what they're for. (I can worry about that later, but others find it easier to understand things given a motivating example.) And some people haven't got their heads around first-class functions yet. So while this would be my preferred explanation if I was talking to a version of me who didn't know decorators yet, it's not the best for everyone. [1] This hasn't previously occurred to me, and I've never seen it explored, but I just verified that it works: def const(fun): return fun() @const def bar(): return 3 print 3 * bar # 9 I'm not sure if this would be useful for anything.