파이썬 - 싱글톤 클래스

안녕하세요, 능력을 키우고 있는 프로그래머 여러분! 오늘은 파이썬 프로그래밍의 세계로 흥미진진한 여행을 떠나보겠습니다. 우리의 목적지는 무엇인가요? 싱글톤 클래스의 신비로운 땅입니다! 그리스럴게도, 이 것이 다소 두려운 것처럼 들릴지라도 걱정 마세요 - 이 튜토리얼 끝에는 싱글톤 마스터가 된 당신이 될 것입니다. 그럼, 이제 들어가보겠습니다!

Python - Singleton Class

싱글톤 클래스란 무엇인가요?

코드를 작성하기 전에 싱글톤 클래스가 무엇인지 이해해보겠습니다. 비디오 게임을 하고 있는데, 그 게임에서 당신이 통제하는 플레이어 캐릭터가 오직 하나라고 상상해보세요. 게임을 저장하고 다시 불러오는 횟수와 관계없이, 항상 같은 캐릭터를 통제한다는 것인데요. 이것이 싱글톤 클래스가 프로그래밍에서 하는 일의 핵심입니다 - 클래스가 오직 하나의 인스턴스를 가지도록 하고, 그 인스턴스에 대한 전역 접근점을 제공합니다.

파이썬에서 싱글톤 클래스 만들기

파이썬에서는 싱글톤 클래스를 만드는 여러 가지 방법이 있습니다. 우리는 두 가지 주요 방법을 탐구하겠습니다: __init____new__를 사용하는 방법입니다. 하지만 먼저, 우리가 왜 싱글톤 클래스를 필요로 할까요?

왜 싱글톤을 사용하나요?

싱글톤은 프로그램에서 클래스의 인스턴스가 오직 하나만 존재하도록 보장하고 싶을 때 유용합니다. 이는 다음과 같은 경우에 도움이 될 수 있습니다:

  1. 전역 상태 관리
  2. 시스템 전체에서 작업 조정
  3. 데이터베이스 연결과 같은 공유 자원 관리

이제, 손끝을 씻고 코드 작성을 시작해보겠습니다!

__init__ 사용하기

첫 번째 방법은 __init__ 메서드를 사용하는 것입니다. 이 메서드는 객체가 생성될 때 호출됩니다.以下是如何使用__init__创建Singleton的方法:

class Singleton:
_instance = None

def __init__(self):
if Singleton._instance is None:
Singleton._instance = self
else:
raise Exception("This class is a singleton!")

@staticmethod
def get_instance():
if Singleton._instance is None:
Singleton()
return Singleton._instance

# 사용법
s1 = Singleton.get_instance()
s2 = Singleton.get_instance()
print(s1 is s2)  # 출력: True

# 이 코드는 예외를 발생시킵니다
# s3 = Singleton()

이 코드를 분석해보겠습니다:

  1. 클래스 변수 _instance를 정의하여 단일 인스턴스를 저장합니다.
  2. __init__ 메서드에서 이미 인스턴스가 존재하는지 확인합니다. 만약 없다면 새로 만듭니다. 만약 있다면 예외를 발생시킵니다.
  3. get_instance() 메서드를 제공하여 싱글톤에 접근할 수 있습니다. 이 메서드는 인스턴스가不存在할 경우 새로 만들고, 이미 존재하면 기존 인스턴스를 반환합니다.

이 코드를 실행하면 s1s2는 같은 인스턴스가 됩니다. 새 인스턴스를 직접 생성하려고 시도하면(예: s3 = Singleton()) 예외가 발생합니다.

__new__ 사용하기

이제 __new__ 메서드를 사용하는 다른 방법을 살펴보겠습니다. 이 메서드는 새 인스턴스를 생성할 때 __init__보다 먼저 호출됩니다.

class Singleton:
_instance = None

def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance

# 사용법
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # 출력: True

이 코드에서는 다음과 같은 일이 일어나고 있습니다:

  1. __new__ 메서드를 재정의하여 새 인스턴스를 생성하고 반환합니다.
  2. _instance가 None이면 새 인스턴스를 super().__new__(cls)를 사용하여 생성합니다.
  3. 항상 _instance를 반환합니다, 새로 만들어진 인스턴스이거나 기존 인스턴스일지라도.

이 방법은 약간 더 간결하고, 별도의 get_instance() 메서드를 필요로 하지 않습니다.

두 가지 방법 비교

이 두 가지 방법을 비교하는 편리한 표를 살펴보겠습니다:

메서드 장점 단점
__init__ - 더 명확한 제어
- 직접 인스턴스화를 방지할 수 있음
- 별도의 get_instance() 메서드 필요
- 약간 더 복잡
__new__ - 더 간결
- 직접 인스턴스화 작동
- 덜 명확한 제어
- 초보자에게는 덜 직관적

두 가지 방법 모두 같은 목표를 달성하므로, 선택은 종종 개인의 선호도나 프로젝트의 특정 요구사항에 따라 다릅니다.

실제 세계 예제

마무리로, 실제 세계의 예제를 살펴보겠습니다. 게임을 만들고 있을 때, 오직 하나의 플레이어 캐릭터만 존재하도록 보장하려고 한다고 가정해봅시다:

class PlayerCharacter:
_instance = None

def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.name = "Hero"
cls._instance.health = 100
cls._instance.level = 1
return cls._instance

def level_up(self):
self.level += 1
print(f"{self.name} leveled up to level {self.level}!")

# 사용법
player1 = PlayerCharacter()
player2 = PlayerCharacter()

print(player1.name)  # 출력: Hero
print(player2.name)  # 출력: Hero

player1.level_up()  # 출력: Hero leveled up to level 2!
print(player2.level)  # 출력: 2

이 예제에서는 PlayerCharacter를 여러 번 생성해도 항상 같은 인스턴스를 얻습니다. 이를 통해 게임에서 플레이어 캐릭터가 일관된 상태를 유지하게 됩니다.

그리고 이렇게 끝납니다! 파이썬에서 싱글톤 클래스를 만드는 방법을 마스터하셨습니다. 기억해주세요, 강력한 도구는 소중히 사용해야 합니다. 싱글톤은 전역 상태나 공유 자원을 관리하는 데 عالی하지만, 과도하게 사용하면 코드가 테스트하고 유지보수하기 어려워질 수 있습니다.

계속 연습하고, 코드를 작성하며, 가장 중요한 것은 즐기세요! 다음 번에 뵙겠습니다, 즐거운 프로그래밍 하세요!

Credits: Image by storyset