클래스도 실행 중 만들어지는 객체다. 보통 클래스의 타입은 `type`이고, 메타클래스는 클래스 객체를 만드는 방식을 바꾼다.
class Plugin:
registry = {}
def __init_subclass__(cls, *, name: str, **kwargs):
super().__init_subclass__(**kwargs)
Plugin.registry[name] = cls
class Greedy(Plugin, name="greedy"):
pass클래스 본문은 별도 이름 공간에서 실행되고, 그 결과를 메타클래스가 클래스 객체로 만든다. `type(name, bases, namespace)`로 같은 일을 동적으로 할 수 있다.
두 베이스가 서로 다른 호환되지 않는 메타클래스를 가지면 메타클래스 충돌이 난다. 프레임워크의 메타클래스를 무심코 섞지 않는 이유다.
메타프로그래밍은 선언 코드를 줄이지만 실행 흐름과 도구의 추론을 어렵게 한다. 사용자가 읽어야 하는 규칙을 숨기지 말고, 생성된 속성과 등록 시점을 문서화하고 테스트한다.
댓글
0개아직 댓글이 없습니다.