[Python-ideas] Multiple arguments for decorators

Emanuel Barry vgr255 at live.ca
Mon Nov 30 21:01:39 EST 2015


> Date: Tue, 1 Dec 2015 12:43:28 +1100
> From: rosuav at gmail.com
> CC: python-ideas at python.org
> Subject: Re: [Python-ideas] Multiple arguments for decorators
> 
> 
> Other than @property, are there any use-cases you know of?

Not in the builtins/stdlib, but I do have decorators that I'd probably rewrite to support the new syntax. In one of my projects I work around this by some other means, but it looks ugly.
> > Method 1: Add parens around all arguments
> 
> Definitely -1 on this syntax - it'd make incomplete lines of code hard
> to diagnose.

Yep, not surprised -- I only included it because that was the first idea I had, but I myself don't like it :)

> > Method 2: Specify how many arguments in the decorator
> 
> -0.5 on this syntax. It's too much action-at-a-distance; if the three
> functions are really trivial, then it wouldn't be too bad, but
> otherwise how do you know that "def x(self):" is making the deleter?
I guess it does make it a bit of a hassle to maintain, maybe if it was combined with another one it would make sense. We'll see.
> > Method 3: Specify arguments using the parameters' names
> 
> This is very close to the existing syntax for @property, and it better
> adorns the individual functions. +0.5. What happens if you rename the
> property, though? How about this:
> 
> class Foo:
>     def __init__(self):
>         self._x = 42
>     @property
>     def x(self): # First positional parameter
>         return self._x
>     def :fset(self, value): # Named parameter
>         self._x = value
>     def :fdel(self): # Another named parameter
>         del self._x
> 
> Remove the repetition of the name "x", and then there's no chance of
> getting it wrong.
I personally don't like this, the colon there looks weird to me. And you're just ignoring the first method's name and passing it positional, unlike the others which are named. I like the general idea you're bringing though, but it could use a tweak or three imo.
> But it's sounding here more like you're creating a block of code. And
> that, to my mind, suggests that it should be indented. Something like:
> 
> class Foo:
>     def __init__(self):
>         self._x = 42
>     with @property as x:
>         def fget(self):
>             return self._x
>         def fset(self, value):
>             self._x = value
>         def fdel(self):
>             del self._x
> 
> This groups the three functions, and their names would be available to
> use as keyword arguments. It would be rather different from current
> with-block semantics, though. Effectively, it'd be something like
> this:
> 
> 1) Evaluate the decorator itself (in this case, the simple name
> 'property'), but don't call it.
> 2) Create a new scope, nested inside the current scope. (Similar to a
> list comp.)
> 3) Execute the indented block in that scope.
> 4) Call the decorator, passing all names bound in this scope as
> keyword arguments.
> 5) Bind the return value of the decorator to the given name.
> 
> Thoughts?

Glancing at this, it seems to me that "property" is having a unary @ operator applied to it, but I guess that since the possibility to introduce a unary @ operator shrank down to exactly 0 when the decorator syntax was added, that's not really an issue. I'm also not sure about overloading the semantics of the 'with' statement.
Nevertheless, I like this approach. I wonder if something similar (using a with statement) can be achieved right now. Probably, with the use of vars and sys._getframe (I never said it would be clean!)
> ChrisA

Thanks for your input! 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151130/eca11616/attachment.html>


More information about the Python-ideas mailing list