0. Introduction
- Meta class에 대한 의견
“Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why).”
– Tim Peters –
Meta class를 배우는 이유
- Tim Peters가 언급한 것처럼 아직은 필요성을 못 느끼지만, 여러 오픈 소스들에서는 이 meteaclass를 활용하여 작성된 경우가 매우 많으므로, class의 형성 원리를 이해한 후 오픈 소스를 보다 잘 이해하기 위해 학습한다.
파이썬에서는 클래스도 포함하여 모든 것들이 객체다.
- 공식 레퍼런스에서도 클래스와 객체를 혼용해서 사용한다.
이번 chapter에서의 목표는 최종적으로 Custom Meta class를 만들기 위함이다.
1. Type: function and metaclass
- 첫 번째: type() 함수를 통해서 해당 인스턴스 및 클래스의 상위 클래스가 무엇인지 확인할 수 있다.
- 두 번째: type class는 class of class로, 클래스를 만들어내는 meta class다.
|
|
type
의 상위 클래스도type
이 출력되었다.- 그러면 다른 자료형들의 상위 클래스도 알아보자.
|
|
여러 자료형들의 상위 클래스가
type class
임을 확인했다.그러면 다음과 같은 사실들을 알 수 있다.
- 여러 자료형들은 class를 기반으로 만들어졌다.
- 각 class들의 상위 클래스는(원형은)
type class
다. type class
의 상위 클래스는(원형은)type class
다.
이
type class
를metaclass
라 한다.- 모든 클래스들은 이 type metaclass의 인스턴스들이다.
- 즉, 모든 클래스들은 type metaclass로부터 만들어졌다.
- 모든 클래스의 원형은 type metaclass다.
- 모든 클래스들은 이 type metaclass의 인스턴스들이다.
2. Metaclass의 이점
1. type function을 통해서 동적으로 생성한 metaclass를 통해서 custom metaclass를 생성할 수 있다.
- meta class를 통해 클래스 구현 레벨에 직접 관여할 수 있기 때문에,
- 의도하는 방향으로 클래스를 커스텀할 수 있다.
- 단 `type class` 이상으로는 관여할 수 없다.
2. framework 작성 시 필수다.
- 1번의 이유처럼 의도하는 방향대로 직접 클래스 생성에 관여할 수 있기 때문에,
- 범용적인 프레임워크 개발, 패키지 개발에 사용된다.
- Django의 내부를 보면 이 metaclass를 사용하여 구현할 것을 알 수 있다.
- 많은 세계적인 파이썬 user들은 meta class를 바탕으로 선언한 후, 원하는 대로 구현한다.
3. type 함수를 통해서 클래스를 동적으로 생성 가능하기 때문에, custom metaclass 생성이 가능하다.
4. meta class를 바탕으로 엄격한 class 사용 그리고, method override를 요구한다.
- Django는 metaclass를 기반으로 만든 ORM framework로,
- DB와 클래스를 일대일로 맵핑하기 때문에 엄격하다.
3. Make a class statically and dynamically
3.1 정적으로 클래스 만들기
class
를 입력하여 만드는 일반적인 방식
|
|
3.2 동적으로 클래스 만들기
동적으로 클래스를 만든다는 건 type() 에 3가지 인자를 입력하여 만드는 방식으로, 필요할 때마다 바로 바로 클래스를 만들어낼 수 있다는 걸 의미한다.
type([name], [bases], [dct])
[name] : 만들려는 클래스의 이름 을 명시한다. 그리고, 만들어진 클래스의
__name__
속성이 된다.[bases] : 만들려는 클래스에게 상속할 클래스 이름 을 명시한다. 이 때, tuple type으로 입력한다. 이는 클래스의
__base__
속성이 된다.[dct] : class body에 있는 속성, method 들을 포함하는 namespace dictionary를 명시한다. 이는 클래스의
__dict__
속성이 된다.
|
|
4. Custom metaclass 만들기
Metaclass를 상속한다는 것의 의미
- type class를 상속받는다.
- metaclass 속성을 사용한다.
- custom metaclass 생성하면 다음 일들이 쉬워진다.
- 클래서 생성 가로채기(intercept) = 후킹(hooking)
- 잡아채서 원하는 기능을 보충하고 수정하는 것
- 클래스 수정하기 (modifiy)
- 클래스 개선(기능 추가)
- 수정된 클래스 반환
- 클래서 생성 가로채기(intercept) = 후킹(hooking)
4.1 Custom metaclass란?
type meta class에서 파생되어 사용자가 의도한 대로 작동하도록 만든 metaclass
- Custom Metaclass가 필요한 이유 를 다음 코드를 통해서 알아보자.
|
|
위와 같은 Error가 발생된 이유는 파이썬이 이를 허용하지 않기 때문이다.
- Why?? type은 모든 클래스들이 만들어지는 기본 토대인 meta class이기 때문에, 사용자가 만질 수 없다.
그래서 type으로부터 만들어지는 custom metaclass를 만드는 것이다.
Custom Metaclass 만드는 단계: type metaclass로부터 파생된 metaclass를 정의하기
- definition head를
class <custom metaclass name>(type):
로 작성하자. - 새롭게 정의한
__new__
method 역할- 상위 metaclass의
__new__
method를super()
function을 통해서 새로 만들어지는 클래스에게 할당한다.
- 상위 metaclass의
- definition head를
|
|
4.2 Ex1 with Type 상속 X
- 그러면 custom metacalss를 생성해보자.
- 다음 것들에 유의해서 보자.
- class가 아니어도 self를 사용하는 것
- class 내부가 아닌 외부에 function을 정의하여, component 식으로 필요할 때마다 꺼내서 custom metaclass에 사용할 수 있다.
- open source에서 이런 방식을 많이 사용한다.
- 동적으로 class 만들 때, 상속할 class로 list를 입력함에 따라 어떻게 흘러가는지.
|
|
- base에 list를 입력하여, list class를 상속받았기 때문에, list object를 class롤 받을 수 있다.
- list만의 모든 method를 사용할 수 있으면서, 추가한 method까지 사용할 수 있다.
dir()
로 확인한 속성을 보면 list에 사용되는 method들이 있는 것을 확인할 수 있다.
4.3 Ex2 with Type 상속 O
Ex1 에 대한 내부 작동 원리를 보여주는 예제
__new__
: class의 new instance를 만들기 위해 호출되는 static method- 사용자 정의 메타 클래스에서 클래스 생성을 customizing 하기 위해 사용된다.
실행 순서:
__new__
->__init__
->__call__
__new__
가 class의 instance를 return하지 않으면, 새 instance의__init__
은 호출되지 않는다.
|
|