Python
python metaclass
Prower
2022. 8. 6. 05:22
728x90
반응형
python에서 클래스
- python에서는 클래스를 객체로 취급한다.
class Foo:
pass
- 이렇게 클래스를 선언하는건 Foo 라는 이름의 객체가 메모리에 올라갔다는 것을 의미한다.
foo = Foo()
- 위에서 말했던 것 처럼 python에서는 클래스도 객체이기 때문에 Foo 라는 객체가 생성됨과 동시에, Foo 클래스를 통해 foo 라는 객체를 생성했다는 의미가 된다.
- 클래스도 객체이므로 변수 할당, 메서드 인자로 전달 등이 가능하다.
class Foo:
pass
def print_object(v):
print(v)
print_object(Foo)
var = Foo
print(var)
type
- type은 2가지 기능을 갖고 있다.
자료형 확인
- 일반적으로 우리가 아는 기능인 자료형 확인이다.
- type의 인자로 객체를 삽입하면 해당 객체의 자료형을 반환한다.
메타클래스
- 객체는 클래스로 부터 생성된다.
- python에서 클래스가 객체라면 클래스(객체)를 생성하는 클래스도 있을 수 있다.
- 메타클래스는 이처럼 객체로서의 클래스를 생성하는데 사용하는 클래스이다
- python에서는 type이 메타클래스이다. 즉, type으로 부터 클래스를 생성할 수 있다.
예시
foo = type("Foo", (), {})
print(foo)
>
<class '__main__.Foo'>
- type은 3개의 인자를 받아 클래스를 생성한다.
- 생성할 클래스의 이름
- 상속받는 클래스, tuple
- 해당 클래스의 속성과 메서드, dictionary
- type 사용하면 다음과 같이 클래스를 생성할 수 있다.
class Foo:
num = 0
def add(self, number):
self.num += number
def print_num(self):
print(self.num)
type을 통한 생성
def add(self, number):
self.num += number
def print_num(self):
print(self.num)
Foo = type("Foo", (), {
"num": 0,
"add": add,
"print_num": print_num
})
foo = Foo()
foo.add(7)
foo.print_num()
>
7
관계 정리
- python에서는 버전에 따라 old type class, new type class가 존재한다.
- 일반적으로 python 2버전의 클래스를 old type class로 분류한다. 해당 클래스는 type 을 상속하고 있지 않으며, 클래스로 부터 생성된 객체의 자료형은 instance 라는 type으로 표기된다.
- python3에서 클래스는 new type class로 분류한다. type을 상속하며, 클래스로 부터 생성된 객체의 자료형은 해당 클래스를 반환한다.
class Foo:
pass
foo = Foo()
print(type(Foo))
print(type(foo))
>
<class 'type'>
<class '__main__.Foo'>
- 위에서 type은 메타클래스이며, 클래스는 객체로 취급된다고 했다.
- python의 클래스는 type으로 부터 생성된 객체이며, 그 객체의 자료형은 type이다.
- 그렇다면 type의 자료형은 어떤것일까
type(type)
>
<class 'type'>
- type의 자료형은 type 그 자체가 된다.
- 여기서 각 관계를 다음과 같이 정리해 볼 수 있다.
- foo는 Foo라는 클래스로 부터 생성된 객체이다.
- Foo는 type이라는 메타클래스로 부터 생성된 객체이다.
- type은 type이라는 메타클래스로 부터 생성된 객체이이며, 그 자체의 객체이다.
생성자 호출시 발생하는 과정
- 일반적으로 객체 생성을 할 때 다음과 같은 방식으로 생성한다.
class Foo:
pass
foo = Foo()
- python에서 class를 메서드로 호출할 때 __call__ 매직 메서드가 호출된다.
- Foo의 __call__ 메서드를 호출하면 다음과 같은 작업이 발생한다.
- Foo의 부모 객체의 __call__ 을 호출한다.
- python3 에서 클래스는 type을 상속한다고 했다. 즉, type의 __call__이 호출된다.
- type의 __call__ 메서드는 __new__ 와 __init__ 메서드를 호출한다.
- __new__ 메서드를 통해 객체가 생성되어 메모리에 올라가고 __init__ 메서드를 호출하여 객체를 초기화 한다.
- 즉, python에서 클래스의 생성이란 type의 __call__ 을 호출하는 과정과 동일하다.
- 다음 예시는 위 예시와 동일한 코드이다.
class Foo:
pass
foo = type.__call__(Foo)
print(foo)
>
<__main__.Foo object at 0x100897f40>
728x90
반응형