10

Possible Duplicate:
Private functions / Variables enforcement in python

Can one create an equivalent to the following class with two static properties, one read-only and the other read-write in Python?

class Foo
{
    private static string _rdy = "RO";
    public static string rd
    {
        get { return _rd; }
    }

    private static string _rw = "RW";
    public static string rw
    {
        get { return _rw ; }
        set { _rw = value; }
    }
}

I know read-only class properties are possible in Python, but how I have not seen any examples of read-write class properties in Python. Is it possible? Basically I want:

class classproperty(object):

    def __init__(self, getter
            #, setter
        ):
        self.getter = getter
    #    self.setter = setter

    def __get__(self, instance, owner):
        return self.getter(owner)

    # Could there be a __set__ here?
    #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    #def __set__(self, instance, owner, value):
    #    self.setter(owner, value)
    #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

class Foo(object):

    _ro = "RO"
    _rw = "RW"

    @classproperty
    def ro(cls):
        return cls._ro

    # How would you this?
    #vvvvvvvvvvvvvvvvvvvv
    #@classproperty.setter
    #^^^^^^^^^^^^^^^^^^^^
    #def rw(cls, value):
    #    cls._rw, value

# This is what I need
>>> Foo.ro
RO
>>> Foo.ro = 'X'     # Hypothetical Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class 'Foo' attribute 'ro' is not writable!
>>> Foo.rw
RW
>>> Foo.rw = 'NEW'
>>> Foo.rw
NEW
0

1 Answer 1

20

I think you want to use the property() built-in. http://docs.python.org/2/library/functions.html#property

While conventionally, it is used on an instance, I think you may be able to use it on a metaclass to achieve what you want.

class MetaFoo(type):
    _ro = "RO"
    _rw = "RW"

    def _get_ro(self):
        return self._ro
    def _get_rw(self):
        return self._rw
    def _set_ro(self, value):
        raise AttributeError("class 'Foo' attribute 'ro' is not writable!")
    def _set_rw(self, value):
        self._rw = value
    ro = property(_get_ro, _set_ro)
    rw = property(_get_rw, _set_rw)


class Foo(object):
    __metaclass__=MetaFoo


assert Foo.rw == "RW"
Foo.rw = 'NEW'
assert Foo.rw == "NEW"

assert Foo.ro == "RO"

try:
    Foo.ro = 'X'
except Exception as e:
    assert str(e) == "class 'Foo' attribute 'ro' is not writable!", str(e)
    assert type(e) == AttributeError
Sign up to request clarification or add additional context in comments.

4 Comments

That's great. This is the simplest answer I have seen.
When there are __metaclasses__defined, how could one add documentation strings to these class properties?
There are two ways to use property(). The I showed and as a decorator. The decorator form preserves doc strings. The way I showed, the docstring would be the fourth argument, while the third argument is a delete method for the propery. Again, see the python documentation link I included.
Awesome. This also works with the @property decorator. 'self' in the metaclass should probably be 'cls' though (just for convention).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.