caoimhin
caoimhin

Reputation: 115

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?

Upvotes: 5

Views: 7335

Answers (2)

Gauthier Boaglio
Gauthier Boaglio

Reputation: 10272

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

Upvotes: 2

Andrew Clark
Andrew Clark

Reputation: 208705

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)

Upvotes: 3

Related Questions