PHpullh

PYTHON · 객체지향

metaclass 기초

메타클래스는 "클래스의 클래스"로, 클래스 생성 과정을 커스터마이즈합니다. type을 상속하여 __new____init_subclass__를 오버라이드하면 클래스 생성 시 자동 검증, 등록, 변형이 가능합니다.

객체지향고급metaclasstypesingletonclass-creationinit-subclass

핵심 설명

메타클래스는 "클래스의 클래스"로, 클래스 생성 과정을 커스터마이즈합니다. type을 상속하여 __new____init_subclass__를 오버라이드하면 클래스 생성 시 자동 검증, 등록, 변형이 가능합니다.

Python code

# 1. 기본 메타클래스: 클래스 생성 시 자동 검증
class ValidatedMeta(type):
    def __new__(mcs, name, bases, namespace):
        # 추상 메서드 검증
        if name != 'Base':
            required = getattr(namespace.get('__init__'), '_required_fields', [])
            for field in required:
                if field not in namespace:
                    raise TypeError(f"{name}에 '{field}' 메서드가 필요합니다")
        return super().__new__(mcs, name, bases, namespace)

# 2. 싱글톤 메타클래스
class SingletonMeta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class Database(metaclass=SingletonMeta):
    def __init__(self):
        self.connection = "PostgreSQL 연결"
        print("DB 인스턴스 생성!")

# 테스트
db1 = Database()  # "DB 인스턴스 생성!" 출력
db2 = Database()  # 출력 없음 (같은 인스턴스 반환)
print(f"같은 객체? {db1 is db2}")  # True

# 3. __init_subclass__ (Python 3.6+, 메타클래스 대안)
class Plugin:
    _registry = {}

    def __init_subclass__(cls, plugin_name=None, **kwargs):
        super().__init_subclass__(**kwargs)
        name = plugin_name or cls.__name__
        Plugin._registry[name] = cls
        print(f"플러그인 등록: {name}")

class AudioPlugin(Plugin, plugin_name="audio"):
    pass

class VideoPlugin(Plugin, plugin_name="video"):
    pass

print(f"등록된 플러그인: {list(Plugin._registry.keys())}")

학습 팁

Python 3.6+의 __init_subclass__는 대부분의 메타클래스 사용 사례를 더 간단하게 대체합니다. 메타클래스가 정말 필요한지 먼저 검토하세요.

주의할 점

메타클래스 충돌: 두 부모 클래스가 다른 메타클래스를 사용하면 TypeError가 발생합니다. 이 경우 공통 메타클래스를 만들어야 합니다.

자주 묻는 질문

metaclass 기초란 무엇인가요?

메타클래스는 "클래스의 클래스"로, 클래스 생성 과정을 커스터마이즈합니다. type 을 상속하여 __new__ 나 __init_subclass__ 를 오버라이드하면 클래스 생성 시 자동 검증, 등록, 변형이 가능합니다.

metaclass 기초 학습 시 주의할 점은 무엇인가요?

메타클래스 충돌: 두 부모 클래스가 다른 메타클래스를 사용하면 TypeError 가 발생합니다. 이 경우 공통 메타클래스를 만들어야 합니다.