Why do I get different instances of the same singleton in different modules?
I have 2 files that print a singleton instance, but I get two different instances.
I'm using Singleton code from Gary Robinson.
Here are the files:
test.py
from singleton import Singleton
import untitled
class A(Singleton):
def __init__(self):
super(A, self).__init__()
if __name__ == "__main__":
a = A.getInstance()
print a
untitled.print_a()
开发者_如何学JAVA
untitled.py
def print_a():
import test
print test.A.getInstance()
...and here is the output of python test.py
<__main__.A object at 0xaea270>
<test.A object at 0xaea3f0>
Can someone please explain to me what is happening (apparently at the module level) that is causing this behavior?
The reason you get two singletons is due to the way the modules are being imported. When you execute test.py from the command line, it is not known as test
, it is __main__
. An entry is added to sys.modules
under the name __main__
, and execution proceeds. When untitled imports test, sys.modules
is examined, no module named test
is found, so test.py is executed again to import it. As a result, the class definition for A
is executed twice, producing two distinct classes. The Singleton implementation therefore considers them distinct, and produces two instances.
I don't know why do you need singletons for, but just taking a look at that "singleton mixin" you pointed too reminded me of an old joke chain-email showing the various stages of a programer (d)evolution, with various examples of a hello world program. On that e-mail, the low-point was the "enterprise class senior program" which developed a client server system, implementing various patterns, in order to write "Hello World".
On the same text, the high point, was the "master hacker", which implemented Hello world with a sngle line: echo Hello World!
So, most likely all you need is just a class from which you use the class and not its instances. it will behave like a singleton for all purposes. If you want to make shure it is not instantiated, just raise an exception on the new method:
class SimpleSingleton(object):
@classmethod
def my_singleton_method(cls,):
pass
def __new__(cls):
raise TypeError("Cannot be instantiated")
精彩评论