Python decorators just syntactic sugar? [duplicate] Python decorators just syntactic sugar? [duplicate] python python

Python decorators just syntactic sugar? [duplicate]


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 wrapsdef 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 wrappeddef 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 wrappedclass 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 wrapperclass 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.


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