Immutability

Duncan Booth duncan.booth at invalid.invalid
Wed Jun 28 14:39:43 EDT 2006


Georg Brandl wrote:

> In my opinion property isn't really meant to be used as a decorator since
> it's impossible to create a read-write property. The decorator pattern
> doesn't really fit here.
> 
I agree that property isn't currently intended to be used as a decorator, 
but it isn't actually *impossible* to create a read-write property using 
decorators. Here is one way:

--------- props.py ----------------
from inspect import getouterframes, currentframe
import unittest

class property(property):
    @classmethod
    def get(cls, f):
        locals = getouterframes(currentframe())[1][0].f_locals
        prop = locals.get(f.__name__, property())
        return cls(f, prop.fset, prop.fdel, prop.__doc__)

    @classmethod
    def set(cls, f):
        locals = getouterframes(currentframe())[1][0].f_locals
        prop = locals.get(f.__name__, property())
        return cls(prop.fget, f, prop.fdel, prop.__doc__)

    @classmethod
    def delete(cls, f):
        locals = getouterframes(currentframe())[1][0].f_locals
        prop = locals.get(f.__name__, property())
        return cls(prop.fget, prop.fset, f, prop.__doc__)

class PropTests(unittest.TestCase):
    def test_setgetdel(self):
        class C(object):
            def __init__(self, colour):
                self._colour = colour

            @property.set
            def colour(self, value):
                self._colour = value

            @property.get
            def colour(self):
                return self._colour

            @property.delete
            def colour(self):
                self._colour = 'none'
                
        inst = C('red')
        self.assertEquals(inst.colour, 'red')
        inst.colour = 'green'
        self.assertEquals(inst._colour, 'green')
        del inst.colour
        self.assertEquals(inst._colour, 'none')

if __name__=='__main__':
    unittest.main()
-----------------------------------



More information about the Python-list mailing list