Wrapping classes
bruno modulix
onurb at xiludom.gro
Fri Sep 23 04:46:35 EDT 2005
Jeremy Sanders wrote:
> Is it possible to implement some sort of "lazy" creation of objects only
> when the object is used, but behaving in the same way as the object?
Smells like a Proxy pattern...
> For instance:
>
> class Foo:
> def __init__(self, val):
> """This is really slow."""
> self.num = val
>
> # this doesn't call Foo.__init__ yet
> a = lazyclass(Foo, 6)
>
> # Foo is only initalised here
> print a.num
>
> What I really want to do is make an object which looks like a numarray,
> but only computes its contents the first time it is used.
>
Here's a Q&D, stupid simple, possibly flawed solution:
class LazyProxy(object):
def __init__(self, klass, *args, **kwargs):
self.__klass = klass
self.__args = args
self.__kwargs = kwargs
self.__subject = None
def __lazy_init(self):
if self.__subject is None:
self.__subject = self.__klass(*self.__args,**self.__kwargs)
def __getattr__(self, name):
self.__lazy_init()
return getattr(self.__subject, name)
def __setattr__(self, name, value):
# TODO : there's a better way to do this,
# but I don't remember it ruight now and
# don't have time to search...
if name in ['_LazyProxy__klass',
'_LazyProxy__args',
'_LazyProxy__kwargs',
'_LazyProxy__subject']:
self.__dict__[name] = value
else:
self.__lazy_init()
setattr(self.__subject, name, value)
if __name__ == '__main__':
class Greeter(object):
def __init__(self, name):
self.name = name
def greet(self, who):
return "hello %s, my name is %s" % (who, self.name)
lazy1 = LazyProxy(Greeter, 'toto')
print lazy1.greet('titi')
lazy2 = LazyProxy(Greeter, 'lolo')
lazy2.name = "lili"
print lazy2.greet(lazy1.name)
Every comment, fix etc welcome.
Now there are probably better ways to do this playing with decorators or
meta-classes.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list