I'm learning Python and i've been trying to implement a Singleton-type class as a test. The code i have is as follows:
_Singleton__instance = None
class Singleton:
def __init__(self):
global __instance
if __instance == None:
self.name = "The one"
__instance = self
else:
self = __instance
This works in part but the self = __instance part seems to be failing. I've included some output from the interpretor to demonstrate (the code above is saved in singleton.py):
>>> import singleton
>>> x = singleton.Singleton()
>>> x.name
'The one'
>>> singleton._Singleton__instance.name
'The one'
>>> y = singleton.Singleton()
>>> y.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Singleton instance has no attribute 'name'
>>> type(y)
<type 'instance'>
>>> dir(y)
['__doc__', '__init__', '__module__']
Is it possible to do what i'm trying? If not is there another way of doing this?
Any suggestions welcome.
Cheers.
Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the instance of the class. Singleton pattern is used for logging, drivers objects, caching and thread pool.
The instance can be created using lazy initialization, which means that the instance is not created when the class loads but when it is first used. A class that implements the singleton design pattern must prevent multiple instantiations.
Serialization:- Serialization can also cause breakage of singleton property of singleton classes. Serialization is used to convert an object of byte stream and save in a file or send over a network.
Singleton is a creational design pattern, which ensures that only one object of its kind exists and provides a single point of access to it for any other code. Singleton has almost the same pros and cons as global variables. Although they're super-handy, they break the modularity of your code.
Assigning to an argument or any other local variable (barename) cannot ever, possibly have ANY effect outside the function; that applies to your self = whatever
as it would to ANY other assignment to a (barename) argument or other local variable.
Rather, override __new__
:
class Singleton(object):
__instance = None
def __new__(cls):
if cls.__instance == None:
cls.__instance = object.__new__(cls)
cls.__instance.name = "The one"
return cls.__instance
I've done other enhancements here, such as uprooting the global, the old-style class, etc.
MUCH better is to use Borg (aka monostate) instead of your chosen Highlander (aka singleton), but that's a different issue from the one you're asking about;-).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With