파이썬에서는 모든 것이 객체입니다. 우리가 만드는 클래스 자체도 객체이며, 그 클래스를 만드는 것이 바로 메타클래스입니다.
메타클래스 → 클래스 생성 → 인스턴스 생성
type → MyClass → my_instance
파이썬의 기본 메타클래스는 type입니다. 우리가 class 키워드로 클래스를 만들 때 내부적으로 type이 동작하고 있습니다.
# 우리가 평소에 쓰는 클래스 정의
class Person:
pass
# 파이썬 내부에서는 type이 클래스를 만듦
print(type(Person)) # <class 'type'>
print(type(42)) # <class 'int'>
print(type('hello')) # <class 'str'>
메타클래스를 구현하는 방법은 두 가지입니다.
type(이름, 기반클래스 튜플, 속성 딕셔너리) 형식으로 클래스를 동적으로 생성할 수 있습니다.
# 일반적인 클래스 정의
class Person:
def greeting(self):
print("안녕하세요!")
# type으로 동적으로 동일한 클래스 생성
Person = type('Person', (object,), {'greeting': lambda self: print("안녕하세요!")})
p = Person()
p.greeting() # 안녕하세요!
type을 상속받아 메타클래스를 직접 만들 수 있습니다. 클래스를 만들 때 metaclass= 키워드로 지정합니다.
# type을 상속받아 메타클래스 구현
class MyMeta(type):
def __new__(mcs, name, bases, namespace):
print(f"클래스 생성됨: {name}")
return super().__new__(mcs, name, bases, namespace)
# metaclass 키워드로 지정
class Person(metaclass=MyMeta): # 클래스 생성됨: Person
pass
class Animal(metaclass=MyMeta): # 클래스 생성됨: Animal
pass
메타클래스는 클래스의 동작을 제어할 때 주로 사용합니다. 대표적인 예가 싱글톤 패턴(Singleton Pattern) 입니다.
싱글톤 패턴이란 인스턴스를 단 하나만 생성하도록 강제하는 디자인 패턴입니다. 데이터베이스 연결, 설정 관리처럼 전체 프로그램에서 하나의 객체만 존재해야 할 때 사용합니다.
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 DatabaseConnection(metaclass=SingletonMeta):
def __init__(self):
self.status = "연결됨"
# 인스턴스를 여러 번 생성해도 항상 같은 객체
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(db1 is db2) # True ← 동일한 객체
print(id(db1), id(db2)) # 같은 메모리 주소
메타클래스는 강력하지만 복잡성이 높습니다. 대부분의 경우 더 간단한 방법으로 같은 목적을 달성할 수 있습니다.
| 목적 | 메타클래스 | 대안 |
|---|---|---|
| 인스턴스 동작 제어 | 가능하지만 복잡 | 일반 상속으로 충분 |
| 클래스 생성 시점 제어 | ✅ 메타클래스가 적합 | — |
| 싱글톤 패턴 | 메타클래스로 구현 가능 | 데코레이터로도 구현 가능 |
| 속성 자동 추가/검증 | 메타클래스로 구현 가능 | __init_subclass__로도 가능 |
💡 파이썬의 격언 중에 "메타클래스는 99%의 사용자에게 필요하지 않다"는 말이 있습니다. 실무에서는 메타클래스보다 데코레이터나 상속으로 해결하는 경우가 훨씬 많습니다. 하지만 Django ORM, SQLAlchemy 같은 유명 프레임워크 내부에서 메타클래스가 적극적으로 활용되고 있으므로, 개념을 알아두면 분명히 도움이 됩니다.