Python Singleton / Object Instantiation
Solution 1:
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__
:
classSingleton(object):
__instance = Nonedef__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;-).
Solution 2:
Bruce Eckel's code snippet from Design Pattern: I'm confused on how it works
classBorg:
_shared_state = {}
def__init__(self):
self.__dict__ = self._shared_state
classMySingleton(Borg):
def__init__(self, arg):
Borg.__init__(self)
self.val = arg
def__str__(self): return self.val
x = MySingleton('sausage')
print x
y = MySingleton('eggs')
print y
z = MySingleton('spam')
print z
print x
print y
print ´x´
print ´y´
print ´z´
output = '''
sausage
eggs
spam
spam
spam
<__main__. MySingleton instance at 0079EF2C>
<__main__. MySingleton instance at 0079E10C>
<__main__. MySingleton instance at 00798F9C>
'''
Solution 3:
From Singleton Pattern (Python):
classSingleton(type):
def__init__(self, name, bases, dict):
super(Singleton, self).__init__(name, bases, dict)
self.instance = Nonedef__call__(self, *args, **kw):
if self.instance isNone:
self.instance = super(Singleton, self).__call__(*args, **kw)
return self.instance
classMyClass(object):
__metaclass__ = Singleton
print MyClass()
print MyClass()
Solution 4:
This is about the most basic Singleton you can make. It uses a class method to check whether the singleton has been created and makes a new one if it hasn't. There are more advanced ways of going about this, such as overriding the __new__
method.
classSingleton:
instance = None @classmethoddefget(cls):
if cls.instance isNone:
cls.instance = cls()
return cls.instance
def__init__(self):
self.x = 5# or whatever you want to do
sing = Singleton.get()
print sing.x # prints 5
As for why your code fails, there are several reasons. First, by the time __init__
is called, a new object has already been created, defeating the purpose of the singleton pattern. Second, when you say self = __instance
, that simply resets the local variable self; this would be akin to saying
deff(x):
x = 7# changes the value of our local variable
y = 5
f(y)
print y # this is still 5
Since variables in Python are passed by value and not reference, you can't say self = blah
and have it be meaningful in the way you want. The above Singleton class is more what you want, unless you want to get fancy and look into overriding the __new__
operator.
Solution 5:
self = _instance
This wont do what you are expecting it to do. Read about how Python treats names.
Post a Comment for "Python Singleton / Object Instantiation"