Hacker News new | past | comments | ask | show | jobs | submit login

If I have the following code:

    @auth_required
    def some_view():
        pass
And later I decide to change that decorator to be parameterized:

    @auth_required("basic")
    def some_view():
        pass
I have now created a massive amount of pain for myself if I decide to define auth_required() such that it defaults its argument to "basic", unless I force people to call it as @auth_required(), because of the differing callable signatures.

Some people feel @auth_required() is ugly. That's all.




Apparently there's something pretty big here I'm not getting. If you add a parameter to auth_required, of course you're causing a huge amount of pain because you're totally changing what auth_required means. It's going from being directly applied to some_view to generating a function that is applied to some_view. If every decorator was automatically called, every decorator would have to return a function. Among other consequences, you wouldn't be able to use property as a decorator.

Even if it's inconvenient, python's behavior here is still not surprising. It's perfectly consistent, and more general than automatically adding parentheses.


> Some people feel @auth_required() is ugly. That's all.

The biggest issue here is backwards compatibility. Nowadays I just make a separate decorator that accepts arguments and keep the old one around unchanged. I learned my lesson :)


You may also use a simple wrapper to create decorators which would automatically define @decorator and @decorator().


I could also aim with a bazooka at my foot. Been there done that, lesson learned :-)




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: