Reputation: 29
my first question here:
I've searched the internet and also read several question and answers here before and finally figured out the way of writing the singleton classes for my python codes. I've also read the python documentation about the new() function and some other things but still confused about how and what is mean by all that new(cls, *args, **kw) things etc!
for example I wrote a test code like this:
class Singleton(object):
def __new__(cls, *args, **kwargs):
if '_inst' not in vars(cls):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
class printer(Singleton):
def __init__(self):
print "I am a new Object, and will remain until the end of time!"
if __name__ == '__main__':
printer()
and the result is the text "I am a new Object, and will remain until the end of time!" But how this works, I mean, I don't know how to tell, for example I'm really confused about:
vars(cls): in the line if '_inst' not in vars(cls)
from where the vars(cls) comes out, I didn't declare that before! Can someone please clarify this things in the singleton class for me plus some about the last line
if __name__ == '__main__':
printer()
Upvotes: 1
Views: 263
Reputation: 123662
Instead of using a Singleton, have you considered using a Borg
?
The idea is, because Python stores all the state for instances in an attribute (__dict__
), if you simply reassign that attribute to a class attribute then you can instantiate the class as many times as they want but they will all have the same state.
Upvotes: 2
Reputation: 70148
First of all, this is wrong:
class Singleton(object):
def __new__(cls, *args, **kwargs):
if '_inst' not in vars(cls): # <-- this must of course also be "_instance"
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
An explicit __new__
method can be used like the factory pattern, so when you write printer()
, Python will first call __new__
, passing the class type and the constructor parameters (in this example none).
'_instance' not in vars(cls)
just means to look up whether the class already has an attribute called "_instance" (i.e. the singleton). If not, one is created. The trick with vars
(builtin function, to answer your question) is not necessary, one could also use cls._instance
and catch AttributeError
, for example.
And the last thing:
if __name__ == '__main__':
printer()
This just creates a printer
instance (using Singleton.__new__
) if the script is executed directly (i.e. if __name__ == '__main__'
, not if the module is imported).
Upvotes: 2
Reputation: 42188
You should use modules as singletons in python, because they behave exactly like one.
Here is another question: Is there a simple, elegant way to define singletons?
Upvotes: 2