On Monday, November 30, 2015 6:14 PM, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, Dec 1, 2015 at 1:01 PM, Emanuel Barry <vgr255@live.ca> wrote:
The proposal would be strengthened by more examples. Currently, @property can do something very similar to what your proposal offers, so this is only a small improvement.
Agreed. And it's not clear why other decorators can't just do something similar to what @property does.
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.
Agreed. The way to group things in Python is with an indented suite; trying to read three tiny things at the same level as being controlled by something above all of them isn't too terrible, but if there are three big things, or eight tiny things?
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.
I think this is a bad idea from the start. Only functions and classes have scopes; normal suite do not. If you change that to add "... except the suite of a with statement whose context manager is a decorator", that's no longer a simple rule you can hold in your head.
The nearest I can think of is a nested class definition, which I can make work, but it's definitely ugly:
It seems a lot cleaner to just pass a class to the decorator: class Property: def __init__(self, cls): self.fget = getattr(cls, 'fget', None) self.fset = getattr(cls, 'fset', None) self.fdel = getattr(cls, 'fdel', None) self.doc = getattr(cls, '__doc__', None) # everything below this point is exactly the same as the # existing implementation in the descriptor HOWTO (or # the C implementation in descrobject.c). class Foo: def __init__(self): self._x = 42 @Property class x: def fget(self): return self._x def fset(self, value): self._x = value def fdel(self): del self._x Sure, @call slightly simplifies those 4 lines of boilerplate at the start of Property.__init__, and does the same for every other decorator that you define to be used with @call--but at the cost of making every _use_ of every such decorator uglier, and making things more complex to think through. Is it really worth it? Actually, that's not a rhetorical question; it's hard to guess without seeing more examples beyond @property...