I am trying to create a class that doesn’t re-create an object with the same input parameters. When I try to instantiate a class with the same parameters that were used to create an already-existing object, I just want my new class to return a pointer to the already-created (expensively-created) object. This is what I have tried so far:
class myobject0(object): # At first, I didn't realize that even already-instantiated # objects had their __init__ called again instances = {} def __new__(cls,x): if x not in cls.instances.keys(): cls.instances[x] = object.__new__(cls,x) return cls.instances[x] def __init__(self,x): print 'doing something expensive' class myobject1(object): # I tried to override the existing object's __init__ # but it didnt work. instances = {} def __new__(cls,x): if x not in cls.instances.keys(): cls.instances[x] = object.__new__(cls,x) else: cls.instances[x].__init__ = lambda x: None return cls.instances[x] def __init__(self,x): print 'doing something expensive' class myobject2(object): # does what I want but is ugly instances = {} def __new__(cls,x): if x not in cls.instances.keys(): cls.instances[x] = object.__new__(cls,x) cls.instances[x]._is_new = 1 else: cls.instances[x]._is_new = 0 return cls.instances[x] def __init__(self,x): if self._is_new: print 'doing something expensive'
This is my first venture into overriding __new__
and I’m convinced I’m not going about it the right way. Set me straight, please.
Advertisement
Answer
First, use Upper Case Class Names in Python.
Second, use a Factory design pattern to solve this problem.
class MyObject( object ): def __init__( self, args ): pass # Something Expensive class MyObjectFactory( object ): def __init__( self ): self.pool = {} def makeMyObject( self, args ): if args not in self.pool: self.pool[args] = MyObject( args ) return self.pool[args]
This is much simpler than fooling around with new and having class level pools of objects.