How to adapt the Singleton pattern? (Deprecation warning)
You need to drop any additional arguments you are passing when you construct the object. Change the offending line to:
cls._instance = object.__new__(cls)
or
cls._instance = super(Singleton, cls).__new__(cls)
though I think you'll be fine with the first (diamond inheritance and singletons sound as though they shouldn't be mixed).
P.S. I did try this suggestion and it works for me so I don't know why it didn't work for you.
Edit in response to @dragonx's comment: As pointed out in the comments, object.__new__
will throw an exception if you pass on *args, **kwargs
so the super call to __new__
should not include any arguments apart from cls
. This wasn't the case when the original article was written. Also of course if you choose to base your singleton on some other type such as a tuple
you would then need to pass the appropriate arguments.
So based on the answers from @Sven and @Duncan I found a solution which works for me. The problem actually wasn't in the line of the code raising the TypeError, but in the signature of the __new__()
method. The call of the object.__new__(cls)
shall be without the *args, **kwargs, but they have to remain in the Singleton.__new__()
definition. This is the modified Singleton:
class Singleton(object): """ Singleton class by Duncan Booth. Multiple object variables refers to the same object. http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html """ _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls) return cls._instance
And this is an example of sub-classing (which was the issue):
class Child(Singleton): def __init__(self,param=None): print param print 'Doing another stuff' ch=Child('Some stuff')
I still don't understand why the signature of Child's __init__()
has to match to Singleton's `new(), but this solution works.
I found this pattern described in a Python 3 pattern and idioms source. This should certainly help. I would love to know if it solves your problem, although it may violate the minimal impact condition in your question.