advice about `correct' use of decorator
BJörn Lindqvist
bjourne at gmail.com
Thu Aug 23 08:20:21 EDT 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