advice about `correct' use of decorator

Gerardo Herzig gherzig at fmed.uba.ar
Thu Aug 23 21:49:19 CEST 2007


BJörn Lindqvist wrote:

>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?
>
>  
>
Thanks Björn. Maybe im blind here in my intent to use decorators 
somewhere, but even re-checking you samples (pretty much the kind of 
example i show to my boss), it looks nicer (to me) when using a 
decorator!! I guess im becoming a  `deco junky' :)

Later you expose some interesing points about that login page and 
redirecting stuff...well, im my case, the login page does depends on 
user properties, wich (at this point) are stored in a `session data 
variable' (actually a table row), so the login pages take care about 
user properties, not the decorator itself, but the other part of the page.

I guess decorators has is own public, well, im one of that public. Let 
my be with my deco-junk alone, you bastard :)

Thanks a lot for your opinnions, guys!
Gerardo



More information about the Python-list mailing list