클래스 -> 인스턴스 객체 생성
메타클래스 -> 클래스 객체 생성
type(name, bases, dict)
type()
함수의 목적은 타입을 알아보는 것도 있지만,
새로운 클래스를 만드는 메타클래스의 목적도 있다.
name : 만들 클래스 이름
bases : 부모 클래스의 튜플
dict : 속성 값을 정의하는 심볼 사전
1 2 3 4 5 6 7 8 9 10 11
| class Klass: a = 10 b = 20 Klass = Klass() print(Klass)
Klass2 = type('Klass2', (), {'a':10, 'b':20}) print(Klass2)
print(Klass.a, Klass2.a) print(type(Klass), type(Klass2))
|
-상속 구현
1 2 3 4 5 6 7 8 9 10 11
| class Klass: a = 10 b = 20
class Inheritance(Klass): pass
inheritance = type('Inher', (), {}) print(inheritance) print(inheritance.__bases__)
|
-클래스 동적 구현
1 2 3 4 5 6 7 8 9 10 11
| class Klass(): a = 10 b = 20
def display(self): print(self.a)
Dynamic = type('Dynamic', (Klass,), {'display':display}) res = Dynamic() print(res.display) print(Dynamic.mro())
|
-메타클래스 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class SubType(type): def __init__(class_object, name, bases, class_dict): print('__init__', name) super().__init__(name, bases, class_dict)
Sub1 = SubType('SubMetaClass', (), {}) print(Sub1)
Sub2 = SubType('SubMetaClass2', (), {'foo':lambda self: 'bar'}) sub = Sub2() print(Sub2) print(sub) print(sub.foo())
|
-메서드 자동 추가
1 2 3 4 5 6 7 8 9 10 11 12 13
| class SubType(type): def __new__(class_object, name, bases, class_dict): return type.__new__(class_object, name, bases, class_dict)
class SubType2(type): def __new__(class_object, name, bases, class_dict): class_dict['foo'] = lambda self: 'bar' return type.__new__(class_object, name, bases, class_dict)
Sub = SubType2('SubMetaClass', (), {}) res = Sub() print(res.foo())
|
type
을 super
로 바꾸면 안됨.
__new__()
메서드로 전달되는 클래스와 __init__()
메서드로 전달되는 첫 인수는 다른 객체이다.
1 2 3 4 5 6 7 8 9
| class SubType(type): def __new__(class_object, name, bases, class_dict): print('[__new__]', class_object.__name__, name) return type.__new__(class_object, name, bases, class_dict) def __init__(class_object, name, bases, class_dict): print('[__init__]', class_object.__name__, name) type.__init__(class_object, name, bases, class_dict)
Sub = SubType('SubMetaClass', (), {})
|
__new__()
: 메타클래스
__init__()
: 클래스 객체
메타클래스에 정의된 모든 클래스는 첫 인수로 생성된 클래스 객체를 받는다.
-> 메타클래스의 메서드는 생성된 객체(클래스)를 인수로 받기 때문
1 2 3 4 5 6 7 8 9
| class Klass(type): def who_am_i(class_name): print(f"I am {class_name}")
foo = Klass('Foo', (), {}) print(foo.who_am_i) foo.who_am_i() Klass.who_am_i(foo)
|