реализовать синглтон с метаклассом - PullRequest
5 голосов
/ 01 августа 2011

код ниже, как я реализую синглтон с метаклассом, и он работает хорошо

class Test_MetaClass(type):

    def __init__(cls, name, bases, dict):
        super(Test_MetaClass, cls).__init__(cls, bases, dict)
        cls._instance = None
        print 'Test_MetaClass __init__'

    def __call__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(Test_MetaClass, cls).__call__(*args, **kwargs)
        print 'Test_MetaClass __call__'
        return cls._instance


class A(object):
    __metaclass__ = Test_MetaClass
    def __init__(self):
        print 'A __init__ triggered'

a = A()
b = A()

выход:

Test_MetaClass __init__
A __init__ triggered
Test_MetaClass __call__
Test_MetaClass __call__

мой вопрос, почему b = A() прямо перейти к Test_MetaClass.__call__ и игнорировать __init__?

1 Ответ

2 голосов
/ 01 августа 2011

Разве это не то, что вы хотели?cls._instance не None, поэтому он не будет выполняться type.__call__(cls, *args, **kwargs):

>>> type.__call__(A)
A __init__ triggered
<__main__.A object at 0x00BADB30>

Именно через этот вызов A.__new__ и A.__init__ вызывают для создания / инициализации нового экземпляра.Но для вашего синглтона вам нужен только один экземпляр.

...