3

So I read this page about decorators, but I still don't understand when decorators are useful.

Consider a piece of code defining a function f, and then calling it multiple times. For some reason we want f to do some extra work. So we have 2 ways to do it:

  1. define a new function g which calls f, and does the extra work needed. Then in the main code, replace all calls to f by calls to g
  2. define a decorator g, and edit the code to add @g before calls to f

In the end, they both achieve the same result and the advantage of 2) over 1) is not obvious to me. What am i missing?

Community
  • 1
  • 1
usual me
  • 8,338
  • 10
  • 52
  • 95
  • 5
    The day you need them is when you'll actually find its usefulness. – Paulo Bu Mar 06 '14 at 14:08
  • 1
    Decorators are just syntactic sugar. Anywhere you want to wrap a function or attach side effects to a function, decorators are useful. – Martijn Pieters Mar 06 '14 at 14:10
  • 1
    You can find a lot of good feedback here I think: http://stackoverflow.com/a/489754/463678 – shmup Mar 06 '14 at 14:11
  • 2
    Take a look at the [`@property` decorator](http://docs.python.org/2/library/functions.html#property) for an example of a standard library decorator. Or the [`@functools.total_ordering` class decorator](http://docs.python.org/2/library/functools.html#functools.total_ordering). Or the [`@contextlib.contextmanager()` decorator](http://docs.python.org/2/library/contextlib.html#contextlib.contextmanager). – Martijn Pieters Mar 06 '14 at 14:11
  • Decorators are just a design pattern. Get more info here: http://en.wikipedia.org/wiki/Decorator_pattern – Paulo Bu Mar 06 '14 at 14:12
  • 1
    possible duplicate of [What are some common uses for Python decorators?](http://stackoverflow.com/questions/489720/what-are-some-common-uses-for-python-decorators) – xtofl Mar 06 '14 at 14:13
  • There’s an important thing you’ve missed: if you want to wrap a function `f` with a decorator `g`, you only have to add `@g` *once*—at the declaration of `f`—not every time `f` is used. Therefore option (2) will only ever involve one code change, while (1) could mean dozens. – bdesham Mar 06 '14 at 14:13
  • Its syntactic sugar that makes it easier to read and maintain. Wrapping with functions is just more clutter this way you get to write it in a way that suits the intenion better. All of object oriented notation is syntactic sugar and we find it usefull. – joojaa Mar 06 '14 at 14:14
  • Technically, you don't need Python, since there were languages before Python that did everything Python can do. However, some people find that writing in Python makes it easier to do their job. Decorators are similar; sure you can just use your existing tools (defining a new function), but a decorator might be able to solve exactly the same functional requirements with code that is faster to develop or easier to maintain. – Mark Hildreth Mar 06 '14 at 14:47

1 Answers1

2

Suppose you have a lot of functions f1, f2, f3, ... and you want a regular way to make the same change to all of them to do the same extra work.

That's what you're missing and it's why decorators are useful. That is to say, functions that take a function and return a modified version of it.

The decorator @ syntax is "just" for convenience. It lets you decorate the function as it is defined:

@decorated
def foo():
    # several lines

instead of somewhere after the function definition:

def foo():
    # several lines

foo = decorated(foo)

In fact of course the latter code is pretty horrible, since it means that by looking at the first definition of foo in the source, you don't see the same foo that users will call. So without the syntax, decorators wouldn't be so valuable because you'd pretty much always end up using different names for the decorated and undecorated functions.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699