Live data from Hacker News

A primer on Python decorators

thumbtack.com

21–30 of 45 posts

Re: A primer on Python decorators

#23
post #7

What I really want to know is how a framework such as Flask uses a decorator for the route. How is the correct function picked for a particular route that is defined against the decorator? (Maybe I'm completely misunderstanding this...)

Some might say it's a dangerous abuse of decorators.

Since decorators (generally) run at module load time, any stateful decorator (usually) implies the use of global mutable state, which is (considered by many to be) the root cause of much bad design, convoluted flow, limited reusability and untestability. This is perhaps why most decorators in the standard library are pure (off the top of my head).

This is well beyond the scope of the post but an important and often overlooked point in my opinion.

Re: A primer on Python decorators

#24
post #7

What I really want to know is how a framework such as Flask uses a decorator for the route. How is the correct function picked for a particular route that is defined against the decorator? (Maybe I'm completely misunderstanding this...)

Some might say it's a dangerous abuse of decorators. Since decorators (generally) run at module load time, any stateful decorator (usually) implies the use of global mutable state, which is (considered by many to be) the root cause of much bad design, convoluted flow, limited reusability and untestability. This is perhaps why most decorators in the standard library are pure (off the top of my head). This is well beyo…

In flask, the app.route decorator mutates the app object. There are no globals necessary. Use of globals to maintain state is an orthogonal issue to use of decorators to update registries.

Re: A primer on Python decorators

#25
post #24

Earlier quoted context omitted.

Some might say it's a dangerous abuse of decorators. Since decorators (generally) run at module load time, any stateful decorator (usually) implies the use of global mutable state, which is (considered by many to be) the root cause of much bad design, convoluted flow, limited reusability and untestability. This is perhaps why most decorators in the standard library are pure (off the top of my head). This is well beyo…

In flask, the app.route decorator mutates the app object. There are no globals necessary. Use of globals to maintain state is an orthogonal issue to use of decorators to update registries.

Well either the app object is global, in which case you've got global mutable state, or you're defining your handler functions later than module load time, which is pretty uncommon practice.

Re: A primer on Python decorators

#29
post #20
post #16

To authors: I would avoid try except in this code snippet, a simple if else is more explicit. I would also avoid a = b = c statement. One line per statement is better most of the time.

The Python community generally advocates an "it's easier to ask for forgiveness than permission" coding style. When faced with a condition of the form "if condition a holds, do b, else c", it's very often a better idea to do "let's try b, and do c in case b fails because condition a didn't hold". In this case it's better because you can avoid computing an extra hash of the object in cases where it's already a key of…

Agree with that "try except" is better than "if else" for file handling ("with" is even better).

I am not sure if "try except" is really faster than "if else" in some edge cases in a memoization context, as you claim.

What I am sure is that in a didactic context, where you want people to understand code, something like:

    if args not in stored_results:
        stored_results[args] = fn(*args)

    return stored_results[args]
is much better than that (from the OP):

    try:
        # try to get the cached result
        return stored_results[args]
    except KeyError:
        # nothing was cached for those args. let's fix that.
        result = stored_results[args] = fn(*args)
        return result

Re: A primer on Python decorators

#30
post #24

Earlier quoted context omitted.

In flask, the app.route decorator mutates the app object. There are no globals necessary. Use of globals to maintain state is an orthogonal issue to use of decorators to update registries.

Well either the app object is global, in which case you've got global mutable state, or you're defining your handler functions later than module load time, which is pretty uncommon practice.

You can use the return value of some function as a decorator, as a way to avoid global state and tie the decorator to a given instance of your routing object. (I don't know flask, but this isn't a limitation of python)
Post reply on HN