2021. 10. 18. 17:38ㆍ[개발] 지식/Python
Python 싱글톤 패턴 적용
싱글톤 패턴 적용을 위한 아래 코드 이해를 위해서는 일단 cls와 self의 차이와 용도에 대해서 알아야 한다.
아래는 SQLAlchemy의 sessionmaker를 사용한 세션 팩토리 클래스이다.
class SessionFactory():
def __init__(self):
self._engine = create_engine(
"database_url",
echo=True,
pool_recycle=900,
pool_pre_ping=True,
)
self._session = sessionmaker(autocommit=False, autoflush=False, bind=self._engine)
def getSession(self):
return self._session
이를 사용하려면 아래와 같이 인스턴스를 생성해주고, getSession
함수를 통해 세션을 리턴받는다.
sessionFactory = SessionFactory()
session = sessionFactory.getSession()
그리고 이 세션을 가지고 다니면서 사용하면 된다.
하지만 이는 약간의 위험성을 갖게 된다.
SessionFactory
의 인스턴스를 생성할때마다 DB Connection이 중복으로 생성되기 때문이다.
한번 생성한 세션을 계속 사용하면 된다고 하지만, 공동작업이 이루어지는 개발의 특성상 그것이 보장이 된다고 할 수는 없다.
따라서 인스턴스를 계속해서 생성하더라도 항상 동일한 세션을 받도록 보장하기 위해서는 싱글톤 패턴을 적용해야 한다.
class SingletonInstance:
__instance = None
@classmethod
def __getInstance(cls):
return cls.__instance
@classmethod
def instance(cls, *args, **kargs):
cls.__instance = cls(*args, **kargs)
cls.instance = cls.__getInstance
return cls.__instance
위 코드는 싱글톤 인스턴스를 리턴받기 위한 클래스이다.
이를 SessionFactory
클래스가 상속받아 사용하게 될 것이다.
@classmethod
어노테이션은 해당 함수가 static 임을 명시한다. 즉 인스턴스를 생성하지 않고 사용하 할 수 있는 함수라는 뜻이다.
따라서 SessionFactory
클래스가 이를 상속받았다면 아래와 같이 인스턴스를 생성하지 않고 곧바로 instance
함수를 호출할 것이다.
sessionFactory = SessionFactory.instance()
아래 부분을 좀 더 들여다 보자.
@classmethod
def instance(cls, *args, **kargs):
cls.__instance = cls(*args, **kargs)
cls.instance = cls.__getInstance
return cls.__instance
cls
는 인스턴스가 아닌 클래스 자체를 참조한다.
따라서 cls(*args, **kargs)
이 부분은 SessionFactory의 생성자를 호출해서 그 인스턴스를 cls.__instance
이라는 static 필드에 저장하라는 뜻과 같다.
또한 cls.instance = cls.__getInstance
이 구문을 통해 instance
함수 자체를 __getInstance
함수로 대체한다. 앞으로 SessionFactory
의 instance
static 함수를 호출하면 사실상 __getInstance
가 호출되는 것과 마찬가지이므로 기존에 저장된 cls.__instance
를 리턴한다.
class SessionFactory(SingletonInstance):
def __init__(self):
self._engine = create_engine(
"database_url",
echo=True,
pool_recycle=900,
pool_pre_ping=True,
)
self._session = sessionmaker(autocommit=False, autoflush=False, bind=self._engine)
def getSession(self):
return self._session
SessionFactory
클래스를 SingletonInstance
를 상속받도록 변경한다.
그리고 아래와 같이 사용한다.
sessionFactory = SessionFactory.instance()
그리고 아래처럼 생성한 session 객체는 동일한 인스턴스에서 가져왔으므로 동일성이 보장된다.
sessionFactory1 = SessionFactory.instance()
sessionFactory2 = SessionFactory.instance()
print(sessionFactory1.getSession())
print(sessionFactory2.getSession())
위의 코드는 예시일뿐 모범적인 코드는 아니다.
특히 웹에서는 싱글톤을 보장하는 더 좋은 기법들이나 프레임워크 기능들이 있기 때문에 해당 기능을 활용하는 것이 좋다.
다만 이러한 방식으로 싱글톤을 구현할 수 있다는 것을 아는 것에 의의가 있다고 볼 수 있겠다.
Ref.
'[개발] 지식 > Python' 카테고리의 다른 글
이미지를 Base64 인코딩 문자열로 변환해서 HTML에 삽입하기 (Python 사용) (0) | 2022.07.28 |
---|---|
R vs Python 모델 속도 비교 (0) | 2022.01.26 |
ubuntu에서 apt-get으로 python3.7, pip 설치 및 심볼릭 링크 설정하기 (0) | 2022.01.22 |
Linux(ubuntu)에서 Python 특정버전 설치하기 (1) | 2021.11.26 |
Python with절 문법의 이해 (0) | 2021.10.25 |