Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing arguments to singletons in python

I'm using the following code to instantiate a singleton in python:

class Singleton(type):
    def __init__(cls, name, bases, dic):
        super(Singleton, cls).__init__(name, bases, dic)
        cls.instance = None

    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            if DEBUG:
                print("Creating NEW Orchestrator instance")
        else:
            if DEBUG:
                print("Using EXISTING Orchestrator instance")

            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)

        return cls.instance

The init looks like this:

def __init__(self, arg=None):
    ...

When I instantiate the object it doesn't seem to accept the argument:

Obj = Object("parameter")

arg does not equal "parameter". It is None.

I thought this was the purpose in passing *args to the call. How would I pass an argument upon first instantiating a singleton?

like image 433
caoimhin Avatar asked Jun 19 '13 22:06

caoimhin


People also ask

Can Singleton class have parameters?

A parameter is assigned to the constructor of the singleton class type (as we did in step two). We initialize a public static getObject or getInstance function with a class object as the return value.

Why should you avoid 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.

Is there a singleton in Python?

A Singleton pattern in python is a design pattern that allows you to create just one instance of a class, throughout the lifetime of a program. Using a singleton pattern has many benefits. A few of them are: To limit concurrent access to a shared resource.


2 Answers

With your current Singleton class the following seems to work fine on Python 3.x (which I am assuming you are using based on the print function.

class Object(metaclass=Singleton):
    def __init__(self, arg=None):
        print("creating instance with arg:", arg)

For example:

>>> Object("parameter")
creating NEW Orchestrator instance
creating instance with arg: parameter
<__main__.Object object at 0x7f45f9ce8910>
>>> Object("foobar")   # returns the same instance as the above call
<__main__.Object object at 0x7f45f9ce8910>

Edit: You can do the same sort of thing on Python 2.x, the syntax for specifying the metaclass is just a little bit different:

class Object(object):
    __metaclass__ = Singleton
    def __init__(self, arg=None):
        print("creating instance with arg:", arg)
like image 152
Andrew Clark Avatar answered Sep 29 '22 07:09

Andrew Clark


Better use it like this :

class Singleton(type):
    def __init__(cls,name,bases,dic):
        super(Singleton,cls).__init__(name,bases,dic)
        cls.instance=None
    def __call__(cls,*args,**kw):
        if cls.instance is None:
            cls.instance=super(Singleton,cls).__call__(*args,**kw)
        return cls.instance

class Object(object):
    __metaclass__ = Singleton
    def __init__(self, a=None):
        print a 

c = Object("parameter")

I suppose...

Note: This works under Python 2.7.4

like image 20
Gauthier Boaglio Avatar answered Sep 29 '22 07:09

Gauthier Boaglio