singleton problems
Arnaud Delobelle
arnodel at gmail.com
Sun Oct 3 06:54:22 EDT 2010
harryos <oswald.harry at gmail.com> writes:
> hi
> I have been trying out singleton design pattern implementations..I
> wrote this,
>
>
> class Singleton(object):
> _instance = None
> def __new__(self, *args, **kwargs):
> if not self._instance:
> self._instance = super(Singleton, self).__new__(self,
> *args, **kwargs)
> return self._instance
>
>
> class Mysingle(Singleton):
> def __init__(self,name):
> self.name=name
>
> if __name__=='__main__':
> s1=Mysingle('john')
> s2=Mysingle('jim')
> s3=Mysingle('jeff')
> print 's1=',s1,s1.name
> print 's2=',s2,s2.name
> print 's3=',s3,s3.name
>
> This is the result I got
> s1= <__main__.Mysingle object at 0xb776492c> jeff
> s2= <__main__.Mysingle object at 0xb776492c> jeff
> s3= <__main__.Mysingle object at 0xb776492c> jeff
> /home/dev/eclipse_workspace/pylearn/src/designpatterns.py:11:
> DeprecationWarning: object.__new__() takes no parameters
> self._instance = super(Singleton, self).__new__(self, *args,
> **kwargs)
>
> shouldn't the name of s1,s2,s3 be 'john' instead of 'jeff'?
> Also,how do I correct the deprecation problem?Can somebody comment?
That's because overriding __new__ doesn't prevent __init__ from being
executed. The reason for this is that when you do:
MySingle('jeff')
what is executed is:
MySingle.__metaclass__.__call__('jeff')
And as by default, MySingle.__metaclass__ is type (I mean the type
called 'type'), its __call__ method is called. This method calls first
the MySingle.__new__ and then MySingle.__init__ on the result. So you
need to override type.__call__. Here is a very simple implementation to
show you the principle (assuming Python 2.X):
class MetaS(type):
def __call__(self, *args, **kwargs):
# Here, self is the class to be instanciated
instance = getattr(self, "_instance", None)
if instance is None:
instance = super(MetaS, self).__call__(*args, **kwargs)
self._instance = instance
return instance
class Singleton(object):
__metaclass__ = MetaS
class MySingle(Singleton):
def __init__(self, name):
self.name = name
def __str__(self):
return str(self.name)
Now let's see this in action:
>>> a = MySingle("John")
>>> b = MySingle("Jeff")
>>> a is b
True
>>> a.name
'John'
>>> b.name
'John'
HTH
PS: OTOH, singletons are rarely of use in Python as one can use
module-level instances instead.
--
Arnaud
More information about the Python-list
mailing list