개요
디자인 패턴 관련 공부를 하다가 새로 알게된 메타클래스에 대해서 정리한다.
MetaClass
Python에서는 클래스도 객체에 해당한다. 때문에 클래스를 만드는 클래스가 존재하는데, 이를 메타클래스라고 한다. 클래스로 객체를 생성하듯, 메타클래스로 클래스를 생성한다.
메타클래스는 드물게 사용되지만, 파이썬을 사용하는 대부분의 개발자는 이미 메타클래스를 알고 있다. 바로 변수의 데이터 형을 알려주는 type()이 메타클래스이기 때문이다.
type은 데이터 형을 알려줄 뿐만 아니라 클래스를 만드는 기능도 제공하는데 예시와 함꼐 알아본다.
type - 클래스 생성
type으로 클래스를 생성할 때는 type 메서드에 클래스 이름, 부모 클래스 튜플, 속성 및 메서드 딕셔너리를 지정한다.
아래 코드는 이름이 Klass이고, 부모 클래스, 속성과 메서드가 없는 클래스를 생성한다.
Klass = type('Klass', (), {})

만약 속성이나 메서드를 추가하고 싶다면 아래와 같아 작성할 수 있다.
Klass = type('Klass', (object,), {'a': 3, 'm': lambda a, b: a + b})
# 두 클래스는 동일한 클래스다.
class Klass:
a = 3
def m(self, a, b):
return a + b

즉, type을 사용하면 동적으로 클래스를 생성하여 활용할 수 있다.
type - 클래스 생성/상속
클래스가 type을 상속받으면 메타클래스로 정의된다. 이 때 __new__ 메서드에 클래스의 속성과 메서드를 추가할 수 있고, type.__new__ 메서드 결과를 반환해야 한다.
class Klass(type):
# namespace 변수에 클래스의 속성과 메서드를 추가하면 된다.
def __new__(metacls, name, bases, namespace):
# 클래스 내 속성 검증
namespace['desc'] = '계산 클래스'
assert type(namespace['a']) is int, 'a가 정수가 아닙니다.'
namespace['add'] = lambda self, a, b: a + b
return type.__new__(metacls, name, bases, namespace)
메타클래스로 클래스를 만드는 건 type과 동일하게 type 함수를 사용하거나 클래스 정의 시 메타 클래스를 지정해주면 된다.
아래 코드는 type 함수를 사용한 예시다. a 속성을 유리수로 지정해서 값 검증에 오류가 발생한 상태다.

아래 코드는 클래스 정의 시 메타클래스를 지정하는 방식이다.
class Calc(metaclass=Klass):
a = 3
def __init__(self, b):
self.b = b
참고 문서