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 -- http://mail.python.org/mailman/listinfo/python-list