Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 235
Steven Barragán Avatar asked Sep 06 '12 17:09

Steven Barragán


People also ask

Can singleton have multiple instances?

In software engineering, the multiton pattern is a design pattern which generalizes the singleton pattern. Whereas the singleton allows only one instance of a class to be created, the multiton pattern allows for the controlled creation of multiple instances, which it manages through the use of a map.

Why you should not use singletons?

The most important drawback of the singleton pattern is sacrificing transparency for convenience. Consider the earlier example. Over time, you lose track of the objects that access the user object and, more importantly, the objects that modify its properties.

How many instances can singleton have?

Since there is only one Singleton instance, any instance fields of a Singleton will occur only once per class, just like static fields.

What happens if I create more than one object for singleton class?

The "create no more than one instance" is usually a bogus requirement. You create only one instance if you need only one. But you won't die if more than one instance is created. Otherwise, you should rethink the design of the class.


2 Answers

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.

like image 171
mgilson Avatar answered Nov 15 '22 19:11

mgilson


PEP 318 has an example of a singleton decorator for classes:

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    ...

(though I haven't used it myself.)

Btw, about...

I made a singleton like this

Also, you should mention that you copied it directly from ActiveState.

like image 42
aneroid Avatar answered Nov 15 '22 20:11

aneroid