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 가 발생합니다. 이 경우 공통 메타클래스를 만들어야 합니다.
Continue Learning
Python 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.