Почему я получаю разные экземпляры одного и того же синглтона в разных модулях? - PullRequest
0 голосов
/ 28 января 2011

У меня есть 2 файла, которые печатают один экземпляр, но я получаю два разных экземпляра.

Я использую синглтон-код из Гэри Робинсон .

Вот файлы:

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()

untitled.py

def print_a():
    import test
    print test.A.getInstance()

... а вот и вывод python test.py

<__main__.A object at 0xaea270>
<test.A object at 0xaea3f0>

Может кто-нибудь объяснить мне, что происходит (очевидно, на уровне модуля), что вызывает такое поведение?

Ответы [ 2 ]

3 голосов
/ 28 января 2011

Причина, по которой вы получаете два синглета, заключается в том, как импортируются модули. Когда вы запускаете test.py из командной строки, он не известен как test, это __main__. Запись добавляется в sys.modules под именем __main__, и выполнение продолжается. Когда проверяется импорт без названия, sys.modules проверяется, модуль с именем test не обнаруживается, поэтому для его импорта снова выполняется test.py. В результате определение класса для A выполняется дважды, создавая два различных класса. Поэтому реализация Singleton считает их различными и создает два экземпляра.

0 голосов
/ 28 января 2011

Я не знаю, для чего вам нужны синглтоны, но просто взглянув на тот «синглтон-миксин», на который вы указали, напомнил мне старую цепочку электронных писем с шуткой, показывающую различные стадии эволюции программиста (d),с различными примерами программы Hello World.В этом письме нижней точкой была «старшая программа корпоративного класса», которая разработала систему клиент-сервер, реализующую различные шаблоны, для написания «Hello World».

В том же текстевысшей точкой был "главный хакер", который реализовал Hello world с помощью строки sngle: echo Hello World!

Итак, скорее всего, все, что вам нужно, это просто класс, из которого вы используете класс, а не его экземпляры,он будет вести себя как одиночка для всех целей.Если вы хотите убедиться, что он не создан, просто вызовите исключение для метода new :

class SimpleSingleton(object):
    @classmethod
    def my_singleton_method(cls,):
         pass
    def __new__(cls):
         raise TypeError("Cannot be instantiated")
...