Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

class level properties

3 views
Skip to first unread message

Charles D Hixson

unread,
Apr 12, 2008, 3:36:51 PM4/12/08
to pytho...@python.org
I'm trying to construct read-only variables at the class level. I've
been unsuccessful. Any suggestions?

Mixing @classmethod and @property doesn't appear to produce workable
code. Ditto for mixing @classmethod and __getattr__. (The property
approach compiles, but execution says that you can't execute properties.)

I've got a rather large number of variables, so I don't want to define
function accessors for each of them, and I *REALLY* don't want to have
to access them as functions rather than variables or properties.

Arnaud Delobelle

unread,
Apr 12, 2008, 4:18:57 PM4/12/08
to
On Apr 12, 8:36 pm, Charles D Hixson <charleshi...@earthlink.net>
wrote:

Metaclasses, of course!

>>> class MetaX(type):
... @property
... def spam(self): return 'eggs'
...
>>> class X(object):
... __metaclass__ = MetaX
...
>>> X.spam
'eggs'
>>>

HTH

--
Arnaud

Charles D Hixson

unread,
Apr 12, 2008, 7:33:44 PM4/12/08
to Arnaud Delobelle, pytho...@python.org
Thanks. I can make that work. Is it possible to move the entire
implementation of the interpretation of _valueMap, below, into
properties in some similar way? I'm referring to the part managed by
__getattr__ below.
I want a hundred or so read-only variables, and I'm not sure the best
way to achieve it.

class MetaROVars(type):
@property
def simple(self):
return "simple example working"


class test(object):
__metaclass__ = MetaROVars
_valueMap = {
"t1" : (3, "Concept decay rate", "[1, 99]"),
"t2" : (10, "TaskLink decay rate", "[1, 99]"),
}

#@classmethod
def __getattr__(self, name):
if name not in test._valueMap:
raise AttributeError, name
return test._valueMap[name][0]

def describe (self, name):
if name not in test._valueMap:
raise AttributeError, name
return test._valueMap[name][1] + ", lying in the range " +
test._valueMap[name][2]


p = test()
print p.t1
print p.describe("t1")
print p.t2
print test.simple

Arnaud Delobelle

unread,
Apr 13, 2008, 2:06:29 AM4/13/08
to
On Apr 13, 12:33 am, Charles D Hixson <charleshi...@earthlink.net>
wrote:

> Arnaud Delobelle wrote:
> >>>> class MetaX(type):
>
> > ...     @property
> > ...     def spam(self): return 'eggs'
> > ...
>
> >>>> class X(object):
>
> > ...      __metaclass__ = MetaX
> > ...
>
> >>>> X.spam
>
> > 'eggs'
>
> > HTH
>
> > --
> > Arnau
>
> Thanks.  I can make that work.  Is it possible to move the entire
> implementation of the interpretation of  _valueMap, below, into
> properties in some similar way?  I'm referring to the part managed by
> __getattr__ below.
> I want a hundred or so read-only variables, and I'm not sure the best
> way to achieve it.

[snip code sample]

* Do you want to be able to access your attributes from instances as
well or from the class object only? The metaclass trick creates
attributes only accessible from the class object, i.e. in my example
above:

>>> x=X()
>>> x.spam
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'X' object has no attribute 'spam'

* If you have a hundred of so names and values, are you sure you want
to expose them as attributes? It seems to me that they should be in
their own namespace (as keys in a mapping or attributes of a
subobject)

--
Arnaud

Peter Otten

unread,
Apr 13, 2008, 3:17:35 AM4/13/08
to
Charles D Hixson wrote:

> I want a hundred or so read-only variables, and I'm not sure the best
> way to achieve it.

What do you really want to do? I recommend that you forget about bondage and
rely upon displine:

class Test(object):
"""Never change an attribute with an uppercase name."""
SIMPLE = "simple example working"

Now that was easy...

Peter

Charles D Hixson

unread,
Apr 13, 2008, 2:18:58 PM4/13/08
to Peter Otten, pytho...@python.org
What I'm doing it translating Java code which has a large number of
"public static final (type)" variables.

As to your answer ... yes, and with good discipline you can write object
oriented code in C and never need a garbage collector. It's *not* a
good answer. Before I'd chose that one, I'd make it necessary to
instantiate the class before testing the value of it's constants. It's
just that that seems to be a silly requirement, so I'd like to avoid
it. (That's the "solution" that I currently have working with __getattr__.)

Peter Otten

unread,
Apr 13, 2008, 4:34:19 PM4/13/08
to
Charles D Hixson wrote:

> Peter Otten wrote:
>> Charles D Hixson wrote:
>>
>>
>>> I want a hundred or so read-only variables, and I'm not sure the best
>>> way to achieve it.
>>>
>>
>> What do you really want to do? I recommend that you forget about bondage
>> and rely upon displine:
>>
>> class Test(object):
>> """Never change an attribute with an uppercase name."""
>> SIMPLE = "simple example working"
>>
>> Now that was easy...
>>
>> Peter
>>
>>
> What I'm doing it translating Java code which has a large number of
> "public static final (type)" variables.

Ah, Java, the class is an artefact of the language then, and my example
becomes

SIMPLE = "simple example working"

> As to your answer ... yes, and with good discipline you can write object


> oriented code in C and never need a garbage collector. It's *not* a
> good answer. Before I'd chose that one, I'd make it necessary to

Hmm, if you were to choose between a Java dialect without garbage collection
or without the 'final' keyword, would you throw a coin?

> instantiate the class before testing the value of it's constants. It's
> just that that seems to be a silly requirement, so I'd like to avoid

Silly or not, it keeps your code simpler, and simplicity just cannot be
overvalued.

> it. (That's the "solution" that I currently have working with
> __getattr__.)

I'm confident that after you have been coding in Python for a while the
Javaisms will wither away. For now, if you feel that uppercase module-level
names are too big a leap I suggest that you add a __setattr__() method that
records any attempts to modify read-only attributes. That way you'll have a
way to learn whether that particular safety net was a useful investment or
just dead code.

Peter

0 new messages