[Python] Python Singleton Pattern

2021. 4. 27. 18:40 Python/Python 프로그래밍

들어가며

  Design Pattern 중 필요에 의해 자주 사용하는 singleton pattern에 대해서 알아보려고 합니다. Python에서는 Singleton Pattern을 구현하는 방법이 4가지가 있습니다. get_instance와 __init__을 제공하는 방법, main, inner class를 구현하는 방법, decorator를 이용하는 방법(decorator도 하나의 디자인 패턴을 말하는데, 기능 확장이 필요할 때 서브 클래싱 대신에 사용을 합니다.), 마지막으로 가장 많이 사용하는 metaclass를 이용하는 방법입니다. 아무래도 구현하는 방법이 4가지가 있다는 얘기를 해석하면, 한 클래스에서 하나의 객체를 생성하도록 제한을 할 수 있는 방법이 4가지가 있다고 생각하시면 됩니다. 

 

1 .get_instance와 __init__ 을 제공하는 방법

class MySingleton(object):
     INSTANCE = None

     def __init__(self):
        if self.INSTANCE is not None:
            raise ValueError("An instantiation already exists!")
        # do your init stuff

     @classmethod
     def get_instance(cls):
        if cls.INSTANCE is None:
             cls.INSTANCE = MySingleton()
        return cls.INSTANCE 

 

2. main class inner class를 구현하는 방법.

class MySingleton:     
""" A python singleton """
     class __impl:
     """ Implementation of the singleton interface """
         # implement your stuff in here
         pass

    # storage for the instance reference
    __instance = None

    def __init__(self):
        """ Create singleton instance """
        # Check whether we already have an instance
        if MySingleton.__instance is None:
            # Create and remember instance
            MySingleton.__instance = MySingleton.__impl()

        # Store instance reference as the only member in the handle
        self.__dict__[''_Singleton__instance''] = MySingleton.__instance

    def __getattr__(self, attr):
        """ Delegate access to implementation """
        return getattr(self.__instance, attr)

    def __setattr__(self, attr, value):
        """ Delegate access to implementation """
        return setattr(self.__instance, attr, value)

 

3. singleton decorator

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance @singleton class MyClass:
    ...

 

4. SingletonType의 metaclass

class SingletonType(type):
    def __call__(cls, *args, **kwargs):
        try:
            return cls.__instance
        except AttributeError:
            cls.__instance = super(SingletonType, cls).__call__(*args, **kwargs)
            return cls.__instance

class MySingleton(object):
    __metaclass__ = SingletonType

     # ... 

 

출처 : ourcstory.tistory.com/104?category=630693