Python static class property set/get

12,711

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
Share:
12,711
Amal
Author by

Amal

Updated on July 17, 2022

Comments

  • Amal
    Amal almost 2 years

    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
    
  • Amal
    Amal over 11 years
    That's great. This is the simplest answer I have seen.
  • Amal
    Amal over 11 years
    When there are __metaclasses__defined, how could one add documentation strings to these class properties?
  • Joshua D. Boyd
    Joshua D. Boyd over 11 years
    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.
  • Rafe
    Rafe about 11 years
    Awesome. This also works with the @property decorator. 'self' in the metaclass should probably be 'cls' though (just for convention).