Wrapping classes
Pedro Werneck
pedro.werneck at terra.com.br
Fri Sep 23 17:17:34 EDT 2005
I agree this is a case for using metaclasses. What about an
implementation like this ? Seems like checking if init was already
called will slow down all attribute access significantly, but, I don't
like this approach of changing the __init__ method.
class LazyInit(type):
def __new__(self, name, bases, dict):
def __getattribute__(self, attr):
attrs = object.__getattribute__(self, "__dict__")
init = attrs["_init"]
if not init:
args = attrs["_args"]
kwds = attrs["_kwds"]
__init__ = object.__getattribute__(self, "__init__")
__init__(*args, **kwds)
attrs["_init"] = True
return object.__getattribute__(self, attr)
dict['__getattribute__'] = __getattribute__
return type.__new__(self, name, bases, dict)
def __call__(cls, *args, **kwds):
o = object.__new__(cls, *args, **kwds)
o._args = args
o._kwds = kwds
o._init = False
return o
And some simple testing:
>>> class Foo:
... __metaclass__ = LazyInit
... def __init__(self, x, y):
... print "init was called", x, y
... self.x = x
... self.y = y
...
>>> o = Foo(1, None)
>>> o
<__main__.Foo object at 0x402cc96c>
>>> o.x
init was called 1 None
1
>>> o.y
>>>
Regards,
Pedro
On Fri, 23 Sep 2005 10:28:42 +0200
Paolino <paolo_veronelli at tiscali.it> wrote:
> 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?
> >
> A generic approach would override __getattribute__ to let it perform
> the
> __init__ method on not initialized objects.This is a case for using
> metaclasses as even __init__ method must be overridden ad hoc to
> register the arguments for the lazy initialization.
> Probably you want to fine-tune the triggering (specifing which
> attribute should make it happen ),as every look up would trigger.....
>
> class NotInitializedObjects(type):
> def __init__(cls,*_):
> realInit=cls.__init__
> def __newInit__(self,*pos,**key):
> def _init():
> realInit(self,*pos,**key)
> self._init=_init
> cls.__init__=__newInit__
> def __getattribute__(self,attr):
> def getter(attr):
> return object.__getattribute__(self,attr)
> if '_init' in getter('__dict__'):
> getter('_init')()
> del self._init
> return getter(attr)
> cls.__getattribute__=__getattribute__
>
>
> if __name__=='__main__':
> class Class:
> __metaclass__=NotInitializedObjects
> def __init__(self,*pos,**key):
> self.initialized=True
> print 'initializing with',pos,key
> a=Class('arg',key='key') # a fake initialization
>
> try:
> object.__getattribute__(a,'initialized')
> except AttributeError: # should raise
> print 'not initialized'
> else:
> raise
> try:
> a.initialized #every look up would do ,even a print
> except AttributeError:
> raise
> else:
> print 'initialized'
>
>
> Have fun Paolino
>
>
>
>
>
> ___________________________________
> Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB
> http://mail.yahoo.it
> --
> http://mail.python.org/mailman/listinfo/python-list
--
Pedro Werneck
More information about the Python-list
mailing list