반응형

 

metaclass

딱걸렸다. SingletonMixin은 metaclass였던것이다.

http://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/#python-2-metaclass


import threading

class Singleton(type):
    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls._instance = None
        cls._lock = threading.Lock()

    def __call__(cls, *args, **kwargs):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
            return cls._instance

class SingletonMixin(object):
    __metaclass__ = Singleton

이거 재밌는 개념이네.. 아래 코드를 보자.


class Meta(type):
    pass

class Complex1(object):
    pass

class Complex2(Meta):
    pass

class Complex3(object):
    __metaclass__ = Meta

print type(Complex1)
print type(Complex2)
print type(Complex3)

결과
<type 'type'>
<type 'type'>
<class '__main__.Meta'>

전부 type이나 object로 부터 상속받고 있으므로 new-style class들이고 (따라서 metaclass(아마도) 및 super()가 사용 가능)

원래는 type()을 하면은 <type 'type'>이렇게만 나오는데

__metaclass__ 선언을 한순간 type이 바뀜을 알 수 있다.

자, 내가 궁금했던데 아래 코드를 부르는 순간



 def _start_strategies(self):
     self.info('Initializing strategies')

     for strategy in self._strategies:
         import pdb; pdb.set_trace()  # XXX BREAKPOINT
         LiveStrategyManager().start(strategy, self,
                                     paused=not settings.DEBUG)

왜 아래처럼 부모 클래스인 Singleton의 __call__이 불리냐 했던건데



 class Singleton(type):
     def __init__(cls, name, bases, dict):
         super(Singleton, cls).__init__(name, bases, dict)
         cls._instance = None
         cls._lock = threading.Lock()

     def __call__(cls, *args, **kwargs):
         with cls._lock:
             if cls._instance is None:
                 cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
             return cls._instance

 class SingletonMixin(object):
     __metaclass__ = Singleton

알고보니 metaclass로 선언을 해 두어서, 인스턴스를 만드는 순간

(obj = LiveStrategyManager() 를 하지 않았지만

LiveStrategyManger()만 해도 좌변만 없다 뿐이지 instance creation 같다.)

아래처럼 metaclass의 __call__을 먼저 호출해주었던 거시다!

http://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/

이런속성이 있으니까 여기(__call__)에다가 싱글톤을 구현하기 딱 좋았던 것..

궁금증 해결 끝!

반응형

+ Recent posts