-
Notifications
You must be signed in to change notification settings - Fork 0
KR_MetaProgramming
somaz edited this page Mar 6, 2025
·
5 revisions
메타클래스는 클래스의 생성을 제어하는 "클래스의 클래스"이다.
# 기본 메타클래스
class MyMetaclass(type):
def __new__(cls, name, bases, attrs):
# 클래스 속성 수정
attrs['custom_attribute'] = 'Added by metaclass'
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMetaclass):
pass
print(MyClass.custom_attribute) # 'Added by metaclass'# 클래스 데코레이터
def add_methods(cls):
def new_method(self):
return "This is a new method"
cls.new_method = new_method
return cls
@add_methods
class MyClass:
pass
obj = MyClass()
print(obj.new_method()) # "This is a new method"class ValidString(type):
def __new__(cls, name, bases, attrs):
# 문자열 속성 검증
for key, value in attrs.items():
if isinstance(value, str):
attrs[key] = value.strip()
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=ValidString):
name = " John Doe "
title = " Developer "
print(MyClass.name) # "John Doe"
print(MyClass.title) # "Developer"# 동적으로 클래스 생성
def create_model_class(name, fields):
def __init__(self, **kwargs):
for field in fields:
setattr(self, field, kwargs.get(field))
return type(name, (), {
'__init__': __init__,
'fields': fields
})
# 사용 예시
UserModel = create_model_class('User', ['name', 'email', 'age'])
user = UserModel(name='John', email='john@example.com', age=30)class ValidatedField:
def __init__(self, validation_func):
self.validation_func = validation_func
self.name = None
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__.get(self.name)
def __set__(self, instance, value):
if not self.validation_func(value):
raise ValueError(f"Invalid value for {self.name}")
instance.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class User:
name = ValidatedField(lambda x: isinstance(x, str) and len(x) >= 2)
age = ValidatedField(lambda x: isinstance(x, int) and 0 <= x <= 150)class ModelMetaclass(type):
def __new__(cls, name, bases, attrs):
fields = {}
for key, value in attrs.items():
if isinstance(value, Field):
fields[key] = value
attrs['_fields'] = fields
return super().__new__(cls, name, bases, attrs)
class Field:
def __init__(self, field_type):
self.field_type = field_type
class Model(metaclass=ModelMetaclass):
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
class User(Model):
name = Field(str)
age = Field(int)
email = Field(str)class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Database(metaclass=Singleton):
def __init__(self):
self.connection = "Connected"- 메타클래스는 신중하게 사용
- 가독성을 고려한 설계
- 문서화 철저히 하기
- 디버깅 고려
- 표준 라이브러리 패턴 참고