Mixin이란?

홍준식·2024년 8월 11일

Python을 통해 개발하다보면 Mixin을 사용하는 경우를 흔하게 볼 수 있습니다.
Python은 다중 상속을 지원하기에 어떤 클래스에서의 함수를 오버라이딩하는지에 대한 모호함이 존재하고 믹스인은 이러한 다중 상속에서 단독으로 사용되지 않고 클래스에 필요한 기능을 더해주는 역할로 사용됩니다.

Mixin 클래스는 일반적으로 특정 기능을 제공하는 메소드나 속성만을 포함하며, 상태를 가지지 않는 가벼운 클래습입니다.

Mixin의 특징

  • 재사용성 강화: Mixin을 사용하면 공통 기능을 여러 클래스에 쉽게 추가할 수 있습니다. 예를 들어, 로그 기록 기능이나 데이터 검증 기능을 여러 클래스에 적용할 때 유용합니다.
  • 다중 상속: Python의 다중 상속을 활용하여 Mixin을 적용합니다. Mixin 클래스는 주로 여러 클래스에서 공통으로 사용되는 기능을 제공하기 때문에, 다중 상속의 강력한 도구로 사용될 수 있습니다.
  • 독립적 기능: Mixin 클래스는 단독으로 의미 있는 동작을 하지 않으며, 다른 클래스에 기능을 추가하는 데 중점을 둡니다. 따라서 Mixin은 객체를 생성할 필요가 없고, 오로지 다른 클래스와의 조합으로만 사용됩니다.

Python에서 Mixin의 활용

Python에서 Mixin 패턴은 다양한 프레임워크에서 유용하게 사용됩니다. 그 중 대표적인 예로 Django Rest Framework (DRF)를 들 수 있습니다.

먼저 CreateModelMixin 클래스를 살펴보겠습니다. 이 Mixin은 모델 인스턴스를 생성하는 기능을 제공합니다.

class CreateModelMixin:
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}

CreateAPIView는 CreateModelMixin과 GenericAPIView를 조합하여 만들어진 뷰입니다.

class CreateAPIView(mixins.CreateModelMixin,
                    GenericAPIView):
    """
    Concrete view for creating a model instance.
    """
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

Mixin 패턴은 코드 재사용성과 유연한 확정성 및 간결한 코드를 제공하는 장점을 제공합니다.

Mixin 사용 시 주의점

Python에서 다중 상속을 사용할 때에 클래스는 가장 오른쪽 클래스부터 상속하게 됩니다.

class Mixin1(object):
    def test(self):
        print "Mixin1"

class Mixin2(object):
    def test(self):
        print "Mixin2"

class MyClass(Mixin1, Mixin2):
    pass
>> MyClass().test()
Mixin1

즉, 위와 같이 Mixin1, Mixin2를 모두 상속받게되면 가장 왼쪽의 클래스에서 정의된 함수로 오버라이딩되게 되므로 상속 순서에 주의를 기울여야 합니다.

0개의 댓글