classification
Title: decorators for attributes
Type: enhancement Stage: resolved
Components: Interpreter Core Versions:
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: Matthias v/d Meent, ethan.furman
Priority: normal Keywords:

Created on 2016-03-31 23:21 by Matthias v/d Meent, last changed 2016-04-01 00:05 by ethan.furman. This issue is now closed.

Messages (2)
msg262710 - (view) Author: Matthias v/d Meent (Matthias v/d Meent) Date: 2016-03-31 23:21
This is a suggestion, and not final. 

The current ways to define the getter and setter methods for an attribute are 
these two: 

    @property
    def name():
        """ Docstring """
        pass
    
    @name.setter
    def name(value):
        pass
    
    @name.deleter
    def name(value):
        pass

and

    name = property(getter, setter, deleter, docstring)

Of the two ways you can create a property, only the second one allows you to 
use your method definition multiple times, as seen here:

    value = property(getter, setter, deleter)
    value_2 = property(getter, setter, deleter)

but this has the drawback that it can only use defined method. You can go 
around by defining a wrapper method, but even then you will have to put the 
value of your attribute inside the parenthesis of your behaviour definition, 
or put another assignation statement into your file. To prevent this, I propose 
the addition of decorators to attributes, which would behave like the 
decorators on functions:

    class Decorator(object):
        def __init__(self, ref):
            self.val = ref
    
        def __get__(self):
            return self.val
            
        def __set__(self, val):
            self.val = val
    
        def __del__(self):
            del self.val
    
    @Decorator
    val = value
    
    @Decorator
    val_2 = value_2

This should behave just like decorators on functions, but then with the 
functionality of attributes. In the proposed __init__ method ref would be the 
attribute after the evaluation of its declaration, similar to function 
decorators.

The main benefit of this would be that the definition of attributes that behave 
in a similar way (get-, set- and delete-behaviour is the same) you only have to 
define one decorator for multiple attributes and you can change the behaviour 
of your attributes in a more intuitive way. 

The current alternatives are these:

    class Decorator(object):
        def __init__(self, ref):
            self.val = ref
    
        def __get__(self):
            return self.val
            
        def __set__(self, val):
            self.val = val

        def __del__(self):
            del self.val

    @Decorator
    def val():
        pass
    
    @Decorator
    def val_2():
        pass

and

    def decorate(value):
        _value = value
        def get():
            return _value
        def set(value):
            _value = value
        def del():
            del _value
        return property(get, set, del)

    @decorate
    def val():
        pass
    
    val_2 = decorate(1)
    
    val_3 = decorate()
    val_3 = 20

I think it is weird that to create an attribute that is decorated, I need to 
create a function, or need to explicitely call the decorator. This is why the 
decorators were added for functions, I think it might as well be added for 
attributes.
msg262711 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2016-04-01 00:05
Please discuss this idea on the Python-Ideas mailing list first; if that goes well you can bring the idea to Python-Dev; if that also goes well feel free to reopen this issue.

---

In the meantime you could probably do something with a custom descriptor/class decorator pair; if you need help with that you could try the Python-List or StackOverflow.
History
Date User Action Args
2016-04-01 00:05:45ethan.furmansetstatus: open -> closed

nosy: + ethan.furman
messages: + msg262711

resolution: rejected
stage: resolved
2016-03-31 23:21:14Matthias v/d Meentcreate