Computing class variable on demand?
Steven Bethard
steven.bethard at gmail.com
Fri Feb 4 11:56:09 EST 2005
fortepianissimo wrote:
> Thank you so much about this useful tip! I learned the new decorator
> feature of 2.4 simply because of your post.
>
> Unfortunately I don't have luxury right now to run Python 2.4 (for what
> I'm doing anyways). You mentioned the way to do decorator in 2.3. Still
> I have a question here. Here is Scott David Daniels's code for lazy
> initialization:
>
> class Lazy (object):
> def __init__ (self, calculate_function):
> self._calculate = calculate_function
>
> def __get__ (self, obj, _=None):
> if obj is None:
> return self
> value = self._calculate(obj)
> setattr(obj, self._calculate.func_name, value)
> return value
>
> The problem I run into using this for *instance* variables is: the
> setattr() call won't work with a class with __slots__ defined - it
> simply produces error that the attribute we want to modify is
> read-only. Is there a workaround of this problem?
Sounds like you're declaring the class variables in your __slots__ too.
Is this true? I don't think that's necessary -- __slots__ is only for
used for instances. So, for example, this code should work okay:
py> class Foo(object):
... __slots__ = ['baz']
... class __metaclass__(type):
... def bar(self):
... print 'slow initialization'
... return 'apple'
... bar = LazyAttribute(bar)
... def __init__(self, baz):
... self.baz = baz
...
py> f = Foo(1)
py> f.baz
1
py> f.bar
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
AttributeError: 'Foo' object has no attribute 'bar'
py> f.__class__.bar
slow initialization
'apple'
py> Foo.bar
'apple'
Note that if you want to reference the class variable, you have to
specficially go through the class, instead of counting on the instance
lookup as classes without __slots__ can. But as long as you don't
declare 'bar' as a slot, you should still be able to access Foo.bar.
Note that you probably don't want to have 'bar' as both a class variable
and an instance variable -- then the instance variable will just hide
the class variable...
HTH,
Steve
More information about the Python-list
mailing list