advice about `correct' use of decorator

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


On 8/22/07, Gabriel Genellina <gagsl-py2 at yahoo.com.ar> wrote:
> On 22 ago, 10:00, "BJörn Lindqvist" <bjou... at gmail.com> 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

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

or:

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