Python singleton pattern
someone can tell me why this is incorrect as a singleton pattern:
class preSingleton(object):
def __call__(self):
return self
singleton = preSingleton()
# singleton is actually the singleton
a = singleton()
b = singleton()
print a==b
a.var_in_a = 100
b.var_in_b = 'hello'
print a.var_in_b
print b.var_in_a
Edit: The above code prints:
True
hello
100
thank you very much
Part Two
Maybe this is better?
class Singleton(object):
def __new__(cls):
return cls
a = Singleton()
b = Singleton()
print a == b
a.var_in_a = 100
b.var_in_b = 'hello'
print a.var_in_b
print b.var_in_a
Edit: The above code prints:
True
hel开发者_JS百科lo
100
Thanks again.
Singletons are actually really simple to make in Python. The trick is to have the module do your encapsulation for you and not make a class.
- The module will only be initialized once
- The module will not be initialized until the first time it is imported
- Any attempts to re-import the module will return a pointer to the existing import
And if you want to pretend that the module is an instance of a class, you can do the following
import some_module
class SomeClass(object):
def __init__(self):
self.singleton = some_module
Because this is not a singleton. Singleton must be single, your object is not.
>>> class preSingleton(object):
... def __call__(self):
... return self
...
>>> singleton = preSingleton()
>>> singleton2 = preSingleton()
>>> singleton
<__main__.preSingleton object at 0x00C6D410>
>>> singleton2
<__main__.preSingleton object at 0x00C6D290>
This is actualy the Borg pattern. Multiple objects that share state.
That's not to say there's anything wrong with it, and for most if not all use cases it's functionaly equivalent to a singleton, but since you asked...
edit: Of course since they're Borg objects, each instance uses up more memory so if you're creating tons of them this will make a difference to resource usage.
Here's a sexy little singleton implemented as a decorator:
def singleton(cls):
"""Decorate a class with @singleton when There Can Be Only One."""
instance = cls()
instance.__call__ = lambda: instance
return instance
Use it like this:
@singleton
class MySingleton:
def spam(self):
print id(self)
What happens is that outside of the class definition, MySingleton
will actually refer to the one and only instance of the class that exists, and you'll be left with no mechanism for creating any new instances. Calling MySingleton()
will simply return the exact same instance. For example:
>>> MySingleton
<__main__.MySingleton instance at 0x7f474b9265a8>
>>> MySingleton()
<__main__.MySingleton instance at 0x7f474b9265a8>
>>> MySingleton() is MySingleton
True
>>> MySingleton.spam()
139944187291048
>>> MySingleton().spam()
139944187291048
I don't see the problem (if it walks like a duck and quacks like a duck...). Looks like a singleton to me.
It works differently from a Java singleton (for example) because Python uses the same syntax to call a function as to create a new instance of an object. So singleton()
is actually calling the singleton object, which returns itself.
You can do this with your class:
>>> class preSingleton(object):
... def __call__(self):
... return self
...
>>> x = preSingleton()
>>> y = preSingleton()
>>> x == y
False
So, more than one instances of the class can be created and it violates the Singleton pattern.
精彩评论