Files
python-examples/doc/10_07_metaclass.md
2025-01-20 02:26:20 +09:00

4.0 KiB

메타클래스

메타클래스는 파이썬에서 클래스를 생성하는 데 사용되는 클래스입니다. 즉, 클래스의 클래스라고 할 수 있습니다. 일반적인 클래스가 객체를 생성하는 틀이라면, 메타클래스는 그러한 클래스 자체를 생성하는 틀이라고 생각하면 됩니다.

  • 클래스 생성 과정 제어: 클래스가 생성되는 시점에 특정 작업을 수행하거나, 클래스의 속성을 동적으로 변경할 수 있습니다.
  • 클래스 레벨의 로깅: 클래스 생성 시 로그를 남기거나, 프로파일링 정보를 수집할 수 있습니다.
  • 싱글톤 패턴 구현: 특정 클래스의 인스턴스가 단 하나만 존재하도록 제한할 수 있습니다.
  • 데코레이터를 클래스 레벨로 확장: 클래스 전체에 적용되는 데코레이터를 만들 수 있습니다.
class Meta(type):
    def __new__(cls, name, bases, namespace, **kwargs):
        print(f"Creating class: {name}")
        return super().__new__(cls, name, bases, namespace, **kwargs)

class MyClass(metaclass=Meta):
    pass

# MyClass 생성 시 Meta.__new__ 메서드가 호출됨

위 예시에서 Meta는 메타클래스이고, MyClass는 Meta 메타클래스를 사용하여 생성된 클래스입니다. __new__ 메서드는 새로운 클래스가 생성될 때 호출되며, 클래스 생성 과정에 개입하여 추가적인 작업을 수행할 수 있습니다.

메타클래스의 주요 메서드

  • __new__: 새로운 인스턴스를 생성합니다. 클래스를 생성할 때 호출됩니다.
  • __init__: 생성된 인스턴스를 초기화합니다. 클래스가 생성된 후 호출됩니다.
  • __call__: 클래스를 함수처럼 호출할 때 실행됩니다.

싱글턴 패턴의 구현

싱글턴 패턴은 하나의 클래스에 대해 오직 하나의 인스턴스만 생성하고, 이 인스턴스에 대한 전역적인 접근점을 제공하는 디자인 패턴입니다. 즉, 싱글톤 클래스는 프로그램 전체에서 단 한 번만 생성되고, 그 인스턴스를 여러 곳에서 공유하여 사용할 수 있습니다.

  • 전역 상태 관리: 프로그램 전체에서 공유해야 하는 상태를 관리하는 데 유용합니다. 예를 들어, 로그 파일, 설정 정보 등을 관리하는 클래스를 싱글톤으로 만들 수 있습니다.
  • 자원 공유: 단 하나의 인스턴스만 사용하기 때문에 자원 낭비를 줄이고, 자원 공유를 효율적으로 할 수 있습니다.
  • 모듈 간 통신: 서로 다른 모듈 간에 데이터를 주고받을 때, 싱글톤을 통해 중앙 집중식으로 관리할 수 있습니다.
class Singleton:
    __instance = None

    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = super().__new__(cls)
        return cls.__instance
  • __new__ 메서드: 클래스의 인스턴스를 생성하는 메서드입니다.
  • __instance 클래스 변수: 생성된 인스턴스를 저장합니다.
  • 처음 인스턴스를 생성할 때 __instance에 저장하고, 이후에는 이미 생성된 인스턴스를 반환합니다.

상속 제한

파이썬에서 클래스를 상속 불가능하게 만드는 가장 일반적인 방법은 metaclass를 사용하는 것입니다. metaclass는 클래스를 생성하는 클래스로, 클래스 생성 과정에 개입하여 다양한 기능을 구현할 수 있습니다.

class NonInheritableMeta(type):
    def __new__(cls, name, bases, namespace, **kwargs):
        if bases:
            raise TypeError("이 클래스는 상속될 수 없습니다.")
        return super().__new__(cls, name, bases, namespace, **kwargs)

class BaseClass(metaclass=NonInheritableMeta):
    pass

class DerivedClass(BaseClass):  # TypeError 발생
    pass

위 코드에서 NonInheritableMeta는 상속을 불가능하게 만드는 metaclass입니다. __new__ 메서드에서 bases가 비어있지 않으면 (즉, 상속을 시도하면) TypeError를 발생시켜 상속을 막습니다.