Python Custom metaclass

type 외에도 우리는 우리가 원하는 메타클래스를 만들 수도 있다
__metaclass__
Foo 클래스를 만들기 위해 해당 메타클래스를 사용합니다. 발견하지 못한 경우에는 클래스를 만들기 위해 type을 사용
우리가 보통 메타클래스를 introspection, manipulating, inheritance, __dict__와 같은 변수 등을 사용하여 복잡한 무언가를 만드는 데 사용
metaclass 속성은 상속되지 않는다는 점
현재 컨텍스트와 알맞는 클래스를 만들기 위해 API와 같은 곳에 커스텀 메타클래스를 사용
metaclass callable 하기만 하면 댐
메타클래스를 이용하면 다음 일들이 쉬워집니다:
  • 클래스 생성 가로채기(intercept)
  • 클래스 수정하기(modify)
  • 수정된 클래스 반환하기
API 개발에 많이 사용가능
 
 

function style

__metaclass__
# 메타클래스는 우리가 보통 `type`에 전달하는 객체와 같은 객체를 받습니다. def upper_attr(future_class_name, future_class_parents, future_class_attr): """ 대문자로 변환된 속성의 리스트와 함께 클래스 객체를 반환합니다. """ # '__'로 시작하지 않는 모든 객체를 가져와 대문자로 변환합니다. uppercase_attr = {} for name, val in future_class_attr.items(): if not name.startswith('__'): uppercase_attr[name.upper()] = val else: uppercase_attr[name] = val # `type`으로 클래스를 생성합니다. return type(future_class_name, future_class_parents, uppercase_attr) __metaclass__ = upper_attr # 이리하여 모듈 내에 있는 모든 클래스가 영향을 받게 됩니다. class Foo(): # 하지만 글로벌 메타클래스는 object와 함께 작동하지 않습니다 # 하지만 우리는 이 클래스에만 영향을 주고자 여기에 __metaclss__를 정의하면 # object 자식(children)과 함께 작동하게 됩니다. bar = 'bip' print(hasattr(Foo, 'bar')) # Out: False print(hasattr(Foo, 'BAR')) # Out: True f = Foo() print(f.BAR) # Out: 'bip'
 
 

class style

type.__new__
class UpperAttrMetaclass(type): def __new__(cls, clsname, bases, dct): uppercase_attr = {} for name, val in dct.items(): if not name.startswith('__'): uppercase_attr[name.upper()] = val else: uppercase_attr[name] = val return super(UpperAttrMetaclass, cls).__new__(cls, clsname, bases, uppercase_attr)
 
 
 
 
 
 

Recommendations