Read-only class properties

Michael Spencer mahs at telcopartners.com
Mon Jul 11 00:10:36 EDT 2005


Bengt Richter wrote:
...
> 
> class Foo(object):
>     class __metaclass__(type):
>         def __setattr__(cls, name, value):
>             if type(cls.__dict__.get(name)).__name__ == 'Descriptor':
>                 raise AttributeError, 'setting Foo.%s to %r is not allowed' %(name, value) 
>             type.__setattr__(cls, name, value)
>     @classproperty
>     def TheAnswer(cls):
>         return "The Answer according to %s is 42" % cls.__name__
>     @classproperty
>     def AnotherAnswer(cls):
>         return "Another Answer according to %s is 43" % cls.__name__
> 

or, simply put the read-only descriptor in the metaclass:

  Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32
  Type "help", "copyright", "credits" or "license" for more information.
  >>> def classproperty(function):
  ...     class Descriptor(object):
  ...         def __get__(self, obj, objtype):
  ...            return function(objtype)
  ...         def __set__(self, obj, value):
  ...             raise AttributeError, "can't set class attribute"
  ...     return Descriptor()
  ...
  >>> class A(object):
  ...     class __metaclass__(type):
  ...         @classproperty
  ...         def TheAnswer(cls):
  ...             return "The Answer according to %s is 42" % cls.__name__
  ...
  >>> A.TheAnswer
  'The Answer according to __metaclass__ is 42'
  >>> A.TheAnswer = 3
  Traceback (most recent call last):
    File "<input>", line 1, in ?
    File "<input>", line 6, in __set__
  AttributeError: can't set class attribute
  >>> class B(A): pass
  ...
  >>> B.TheAnswer
  'The Answer according to __metaclass__ is 42'
  >>>


this means that the getter doesn't automatically get a reference to the class 
(since it is a method of metaclass), which may or may not matter, depending on 
the application

Michael




More information about the Python-list mailing list