28

Possible Duplicate:
Understanding Python decorators

I am quite new on using Python decorators and from what I understand on my first impression that they are just syntactic sugar.

Is there a more profound use of them for more complex uses ?

Community
  • 1
  • 1
coredump
  • 3,017
  • 6
  • 35
  • 53
  • 2
    There's a comprehensive answer with usage examples here http://stackoverflow.com/questions/739654/understanding-python-decorators#answer-1594484 – Hedde van der Heide Sep 06 '12 at 08:31
  • Thank you. It's really usefull I do not know how to close or delete this post. If someone can do this it would be great. – coredump Sep 06 '12 at 08:34
  • And here is a little tutorial so you can see exactly what they are: https://www.codementor.io/python/tutorial/introduction-to-decorators – Sheena Mar 25 '15 at 09:02
  • No, the syntax of syntactic sugar has limitations. For higher flexibility you can decorate without @ – cards Aug 15 '21 at 11:40

2 Answers2

19

Yes it is syntactic sugar. Everything can be achieved without them, but with a few more lines of code. But it helps you write more concise code.

Examples:

from functools import wraps

def requires_foo(func):
    @wraps(func)
    def wrapped(self, *args, **kwargs):
        if not hasattr(self, 'foo') or not self.foo is True:
            raise Exception('You must have foo and be True!!')
        return func(self, *args, **kwargs)
    return wrapped

def requires_bar(func):
    @wraps(func)
    def wrapped(self, *args, **kwargs):
        if not hasattr(self, 'bar') or not self.bar is True:
            raise Exception('You must have bar and be True!!')
        return func(self, *args, **kwargs)
    return wrapped

class FooBar(object):

    @requires_foo                 # Make sure the requirement is met.
    def do_something_to_foo(self):
        pass

We could also chain/stack the decorators on top of each other.

class FooBar(object):
    @requires_bar
    @requires_foo                 # You can chain as many decorators as you want
    def do_something_to_foo_and_bar(self):
        pass

OK, we could end up with lots and lots of decorators on top of each other.

I know! I'll write a decorator that applies other decorators.

So we could do this:

def enforce(requirements):
    def wrapper(func):
        @wraps(func)
        def wrapped(self, *args, **kwargs):
            return func(self, *args, **kwargs)
        while requirements:
            func = requirements.pop()(func)
        return wrapped
    return wrapper

class FooBar(object):
    @enforce([reguires_foo, requires_bar])
    def do_something_to_foo_and_bar(self):
        pass

This is a small sample just to play with.

jameshfisher
  • 34,029
  • 31
  • 121
  • 167
rantanplan
  • 7,283
  • 1
  • 24
  • 45
  • For that matter, all programming language construct is syntactic sugar. You can always directly write instructions in memory to be executed. This syntactic sugar allows us to write high level logic. – mahoriR Jan 30 '20 at 05:48
  • @Mahori that's obviously false. `def` and `class` constructs are not syntactic sugar for example. There's a pretty concise definition for syntactic sugar in the context of programming languages, look it up. – rantanplan Jan 30 '20 at 10:11
  • @ratanplan You are implying "syntactic sugar" can be used in terms of various language constructs available within a programming language. I used"syntactic sugar" as whole, thus spanning multiple languages (like the original use) - . See original use here - The term syntactic sugar was coined by Peter J. Landin in 1964 to describe the surface syntax of a simple ALGOL-like programming language which was defined semantically in terms of the applicative expressions of lambda calculus Later programming languages, such as CLU, ML and Scheme, extended the term to refer to syntax within a language – mahoriR Jan 30 '20 at 10:33
  • 1
    I used the common term that every body else means when referring to "syntactic sugar". For further info check current wikipedia entry. – rantanplan Jan 31 '20 at 14:02
  • I think that the original problem was about: decoration = syntactic sugar. The answer is NO. You just provide nice examples with @-notation and mentioned the advantages of it that's all – cards Aug 15 '21 at 11:45
1

I really like the decorator syntax because it makes code uber explicit

For example, in Django there's this login_required decorator: https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required

To inject the @login_required behavior for a function/view, all you gotta do is attach the decorator to it (as opposed to putting if: ... else: ... control expressions everywhere etc. )

Read the PEP!

http://www.python.org/dev/peps/pep-0318/

it has losta history on the language decisions that were made, and why

David Lam
  • 4,689
  • 3
  • 23
  • 34