advice about `correct' use of decorator

BJörn Lindqvist bjourne at
Thu Aug 23 14:20:21 CEST 2007

On 8/22/07, Gabriel Genellina <gagsl-py2 at> wrote:
> On 22 ago, 10:00, "BJörn Lindqvist" <bjou... at> wrote:
> > As I said, you can accomplish the exact same thing by calling a
> > function from within the function that requires the user to be logged
> > in.
> >
> > def change_pass():
> >     check_user_logged_in()
> >     ... more stuff here...
> >
> > is less complex (and therefore preferable) than:
> >
> > @check_user_logged_in
> > def change_pass():
> >     ... more stuff here...
> >
> > An important principle in engineering is that you should always strive
> > to make your design as simple as possible. If you have two equal
> > designs, you should always choose the one that is simpler because
> > simple things are easier to understand than complex things.
> I don't see the complexity in this case - both are a single line of
> code. Any internal complexity is hidden by the language. In fact, I

"Hiding" doesn't reduce complexity, quite the opposite.

> consider the decorated function simpler than the other: its body
> represents exactly what the function does, without any distracting
> precondition calls.

Think about how the decorator is implemented. It is a high order
function, taking a function and returning a new function. Something
like this:

def check_user_logged_in(func):
    def f(*args, **kwargs):
        if global_state.the_user.is_logged_in:
            return func(*args, **kwargs)
        return show_login_page()
    return f

def change_pass():
    ... more stuff here...


def check_user_logged_in():
    return global_state.the_user.is_logged_in

def change_pass():
    if not check_user_logged_in():
        return show_login_page()
    ... more stuff here ...

or even:

def change_pass():
    if not global_state.the_user.is_logged_in:
        return show_login_page()
    ... more stuff here ...

> The decorator has some advantages: can have syntax support on your
> editor, can perform some registering/logging, it's even easier to
> quickly check visually if it's here.

The decorator has just as many disadvantages. For example, what if you
want to redirect back to the change_pass page once the user has
pressed the Login button on the login_page? Or if you want to show
different login pages depending on user properties? How much control
flow do you really want to "hide" in your decorator?

mvh Björn

More information about the Python-list mailing list