메타클래스는 클래스의 클래스라고 표현한다.
보통 클래스는 인스턴스를 생성하는 방법을 정의하는 것처럼 템플릿같은 용도로 사용한다.
메타클래스는 그 대상이 클래스가 된다고 생각하면 된다. 클래스가 어떻게 생성되고 동작할 지 정의하는 역할을 한다. 기본적으로 모든 파이썬 클래스는 type이라는 내장 메타클래스를 사용하여 생성됩니다.
즉, 메타클래스는 내가 의도하는 방향으로 클래스를 커스텀하는 것이다.
우리가 흔히 타입을 알기 위해 사용하는 type
함수는 명확히 어떤 것을 반환하는 것인지 알고 넘어가자.
class SampleA(): # Class == Object
pass
obj1 = SampleA() # 변수에 할당, 복사 가능, 새로운 속성, 함수의 인자로 넘기기 가능
# obj1 -> SampleA instance
# SampleA -> type metaclass
# type -> type metaclass
print(obj1.__class__) # <class '__main__.SampleA'>
print(type(obj1)) # <class '__main__.SampleA'>
print('Ex1 > ', obj1.__class__ is type(obj1)) # True
코드를 보면 알 수 있듯이 type
함수가 반환하는 것은 해당 객체(인스턴스)의 __class__
(본래의 원형)이다.
그럼 type
함수에 본래의 클래스를 넣으면 어떻게 되는지 알면 메타클래스에 대해 알 수 있다.
print(type(SampleA)) # <class 'type'>
for cls in (int, str, float, dict, tuple):
print(type(cls)))
"""
<class 'type'>
<class 'type'>
<class 'type'>
<class 'type'>
<class 'type'>
"""
위를 보면 알 수 있는 것이 모든 클래스의 원형은 type
이라는 메타클래스인 것이다.
tpye(Name(이름), Bases(상속), Dct(속성,메소드))
s1 = type('Sample1', (), {})
print('Ex1 > ', s1) # '__main__.Sample1'
print('Ex1 > ', type(s1)) # <class 'type'>
print('Ex1 > ', s1.__base__) # <class 'object'>
print('Ex1 > ', s1.__dict__) # {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'sample1' objects>, '__weakref__': <attribute '__weakref__' of 'sample1' objects>, '__doc__': None}
위 방식처럼 type을 이용하여 미리 정의된 클래스가 아니라 코드로 클래스가 동적으로 정의될 수 있다.
type
클래스의 인자 순서대로 클래스명, 상속받는 객체, 속성 및 메소드 를 받게된다.
class Parent1:
pass
s2 = type(
'Sample2',
(Parent1,),
dict(attr1=100, attr2='hi')
)
print(s2) # <class '__main__.Sample2'>
print(type(s2)) # <class 'type'>
print(s2.__base__) # <class '__main__.Parent1'>
print(s2.__dict__) # {'attr1': 100, 'attr2': 'hi', '__module__': '__main__', '__doc__': None}
print(s2.attr1, s2.attr2) # 100 hi
class SampleEx:
attr1 = 30
attr2 = 100
def add(self, m, n):
return m + n
def mul(self, m, n):
return m * n
s3 = type(
'Sample3',
(object, ), # 생략 가능
dict(attr1=30, attr2=100, add=lambda x, y: x + y, mul=lambda x, y: x * y)
)
위에서 s3와 SmapleEx의 인스턴스는 완전히 동일한 기능을 한다.