Read-only class properties

I'm trying to write a decorator similar to property, with the
difference that it applies to the defining class (and its subclasses)
instead of its instances. This would provide, among others, a way to
define the equivalent of class-level constants:

Advertisements

On 10 Jul 2005 13:38:22 -0700, "George Sakkis" <> wrote:
>I'm trying to write a decorator similar to property, with the
>difference that it applies to the defining class (and its subclasses)
>instead of its instances. This would provide, among others, a way to
>define the equivalent of class-level constants:
>
>class Foo(object):
> @classproperty
> def TheAnswer(cls):
> return "The Answer according to %s is 42" % cls.__name__
>
>>>> Foo.TheAnswer
>The Answer according to Foo is 42
>>> Foo.TheAnswer = 0
>exceptions.AttributeError
>...
>AttributeError: can't set class attribute
>
>I read the 'How-To Guide for Descriptors'
>(http://users.rcn.com/python/download/Descriptor.htm) that describes
>the equivalent python implementation of property() and classmethod()
>and I came up with this:
>
>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()
>
>Accessing Foo.TheAnswer works as expected, however __set__ is
>apparently not called because no exception is thrown when setting
>Foo.TheAnswer. What am I missing here ?
>
I suspect type(Foo).TheAnswer is not found and therefore TheAnswer.__set__ is not
looked for, and therefore it becomes an ordinary attribute setting. I suspect this
is implemented in object.__setattr__ or type.__setattr__ as the case may be, when
they are inherited. So I introduced a __setattr__ in type(Foo) by giving Foo
a metaclass as its type(Foo). First I checked whether the attribute type name was
'Descriptor' (not very general ;-) and raised an attribute error if so.
Then I made a class Bar version of Foo and checked for __set__ and called that
as if a property of type(Bar) instances. See below.

[18:17] C:\pywk\clp>py24 classprop.py
The Answer according to Foo is 42
Foo.notTheAnswer is 'ok'
Another Answer according to Foo is 43
AttributeError: setting Foo.TheAnswer to 123 is not allowed
AttributeError: setting Foo.AnotherAnswer to 456 is not allowed
The Answer according to Bar is 42
Bar.notTheAnswer is 'ok'
Another Answer according to Bar is 43
AttributeError: can't set class attribute
AttributeError: can't set class attribute

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!