프로그램 생애주기 리소스 관리 — class 변수 vs instance 변수
SQLite connection, browser 객체처럼 프로그램 시작~종료까지 하나만 유지해야 하는 리소스를 어디에 둘 것인가.
클래스 변수에 두면 안 되는 이유
class DatabaseManager:
conn = sqlite3.connect("db.sqlite") # 클래스 import 시 즉시 연결 열림
- 초기화 타이밍 제어 불가: 클래스가 import되는 순간 연결이 열린다
- 의도 불명확: "하나만 쓴다"는 보장이 구조에 없음. 인스턴스를 여러 개 만들어도 막을 수 없음
올바른 구조: Singleton + 인스턴스 변수
class DatabaseManager:
_instance = None # 인스턴스 추적용 클래스 변수 (리소스 아님)
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.conn = sqlite3.connect("db.sqlite") # 인스턴스 변수
return cls._instance
db1 = DatabaseManager()
db2 = DatabaseManager()
db1 is db2 # True
실제 리소스(conn)는 인스턴스 변수로. _instance는 싱글턴 보장을 위한 클래스 변수로만 사용.
Python다운 방식: 모듈 레벨 변수
# db.py
conn = sqlite3.connect("db.sqlite")
# 사용하는 곳
import db
db.conn.execute(...)
Python 모듈은 한 번만 import되고 캐싱된다 → 사실상 싱글턴. 오버엔지니어링 없이 동일한 효과.
선택 기준
| 방식 | 언제 적합 | |---|---| | 클래스 변수에 리소스 | 거의 없음 | | 인스턴스 변수 + Singleton | 클래스로 캡슐화·메서드 제공이 필요할 때 | | 모듈 레벨 변수 | 단순한 경우, Python다운 방식 |
관련 노트
- python-class-vs-instance
- Singleton 패턴 → 설계하자 프로젝트에서 더 깊이 다룰 것