통계 정보를 포함하는 메타클래스를 만들어 클래스의 사용 현황(예: 인스턴스 생성 횟수, 메서드 호출 횟수 등)을 자동으로 추적하는 샘플 코드를 작성해 보았습니다.

from collections import defaultdict
from functools import wraps

class StatsMeta(type):
    """통계 정보를 포함한 메타클래스"""
    def __new__(cls, name, bases, dct):
        # 통계를 저장할 딕셔너리 추가
        dct.setdefault('__stats__', {
            'instance_count': 0,  # 생성된 인스턴스 수
            'method_calls': defaultdict(int),  # 메서드 호출 횟수
        })
        # 메서드를 래핑하여 호출 횟수 추적
        for key, value in dct.items():
            if callable(value) and not key.startswith("__"):
                dct[key] = cls.wrap_method(value, key)
        return super().__new__(cls, name, bases, dct)

    @staticmethod
    def wrap_method(method, method_name):
        """메서드 호출 횟수를 추적하기 위한 래핑 함수"""
        @wraps(method)
        def wrapped_method(self, *args, **kwargs):
            # 호출 횟수 증가
            self.__class__.__stats__['method_calls'][method_name] += 1
            return method(self, *args, **kwargs)
        return wrapped_method

    def __call__(cls, *args, **kwargs):
        # 인스턴스 생성 횟수 증가
        cls.__stats__['instance_count'] += 1
        return super().__call__(*args, **kwargs)

    def get_stats(cls):
        """현재 클래스의 통계 정보 반환"""
        return cls.__stats__

# 통계 정보를 추적하는 데이터 클래스
class DataClass(metaclass=StatsMeta):
    def method_a(self):
        print("Method A called.")

    def method_b(self):
        print("Method B called.")

# 사용 예제
if __name__ == "__main__":
    # 클래스 인스턴스 생성
    obj1 = DataClass()
    obj2 = DataClass()

    # 메서드 호출
    obj1.method_a()
    obj2.method_a()
    obj1.method_b()

    # 통계 정보 출력
    stats = DataClass.get_stats()
    print(f"Instance Count: {stats['instance_count']}")
    print("Method Calls:")
    for method, count in stats['method_calls'].items():
        print(f"  {method}: {count}")

코드 설명

  1. StatsMeta 메타클래스:
    • __stats__: 클래스 수준에서 통계를 저장하는 딕셔너리를 추가.
    • wrap_method: 클래스의 메서드를 래핑하여 호출 시 통계 정보를 업데이트.
    • __call__: 인스턴스 생성 시 instance_count를 증가.
    • get_stats: 통계 정보를 반환하는 클래스 메서드.
  2. DataClass:
    • StatsMeta 메타클래스를 사용하여 메서드 호출 및 인스턴스 생성 통계를 자동으로 관리.
  3. 사용 예제:
    • DataClass 인스턴스를 생성하고 메서드를 호출한 뒤, 통계 정보를 출력.

실행 결과 (예시):

Method A called.
Method A called.
Method B called.
Instance Count: 2
Method Calls:
  method_a: 2
  method_b: 1

이 메타클래스는 클래스의 동작을 자동으로 감시하고, 개발 및 디버깅 단계에서 클래스의 사용 통계를 확인하는 데 유용합니다.

+ Recent posts