Steven Barragán Steven Barragán - 2 months ago 11
Python Question

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??

Answer

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(_singlton = 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.