Search code examples
pythonsingletoninit

issue with singleton python call two times __init__


I have a singleton like this

class Singleton:

    class __impl:
        def __init__(self):
            print "INIT"

    __instance = None

    def __init__(self):
        # Check whether we already have an instance
        if Singleton.__instance is None:
            Singleton.__instance = Singleton.__impl()

        # Store instance reference as the only member in the handle
        self.__dict__['_Singleton__instance'] = Singleton.__instance

    def __getattr__(self, attr):
        """ Delegate access to implementation """
        return getattr(self.__instance, attr)

    def __setattr__(self, attr, value):
        """ Delegate access to implementation """
        return setattr(self.__instance, attr, value)

When I made several instances of Singleton I get two calls to init , I mean "INIT" is printed two times, and I supose that it shouldn't happened

Somebody has an idea of what is wrong with this or has a better way to implement this??


Solution

  • Here's a slightly simpler way to write a Singleton:

    class Singleton(object):
        __instance = None
        def __new__(cls):
            if cls.__instance is None:
                cls.__instance = super(Singleton,cls).__new__(cls)
                cls.__instance.__initialized = False
            return cls.__instance
    
        def __init__(self):      
            if(self.__initialized): return
            self.__initialized = True
            print ("INIT")
    
    a = Singleton()
    b = Singleton()
    print (a is b)
    

    although there may be better ways. I have to admit that I've never been fond of singletons. I much prefer a factory type approach:

    class Foo(object):
        pass
    
    def foo_singleton_factory(_singleton= Foo()):
        return _singleton
    
    a = foo_singleton_factory()
    b = foo_singleton_factory()
    print (a is b)
    

    This has the advantage that you can keep getting the same instance of Foo if you want it, but you're not limited to a single instance if you decide 10 years down the road that you don't want a true singleton.