반응형

Python의 추상 클래스와 MutableMapping을 활용한 데이터 구조 설계

Python은 객체 지향 프로그래밍(OOP) 언어로서, 추상 클래스를 통해 명확한 인터페이스를 정의하고 이를 기반으로 다양한 데이터 구조를 설계할 수 있는 기능을 제공합니다. 특히, Python의 collections.abc 모듈에서 제공하는 MutableMapping 추상 클래스를 활용하면, 딕셔너리와 같은 유연한 데이터 구조를 커스터마이즈하고 확장할 수 있습니다.

이 글에서는 Python의 추상 클래스 개념과 MutableMapping을 활용한 데이터 구조 설계 방법을 설명하고, 실질적인 예제를 통해 그 활용 방법을 소개합니다.

추상 클래스 (Abstract Class)

추상 클래스는 하나 이상의 추상 메서드를 포함하는 클래스입니다. 추상 메서드는 선언만 되어 있고, 실제 구현은 제공하지 않습니다. 추상 클래스는 객체를 직접 생성할 수 없으며, 반드시 상속받아 추상 메서드를 구현해야 합니다. 이를 통해 일관된 인터페이스를 강제할 수 있습니다.

추상 클래스의 정의

from abc import ABC, abstractmethod

class AbstractDataStructure(ABC):
    @abstractmethod
    def add(self, item):
        pass

    @abstractmethod
    def remove(self, item):
        pass

    @abstractmethod
    def find(self, item):
        pass

 

위 예제에서 AbstractDataStructure는 추상 클래스이며, add, remove, find 메서드는 추상 메서드로 정의되어 있습니다. 이 클래스는 상속받아 구체적인 구현을 제공해야 합니다.

MutableMapping 추상 클래스

collections.abc 모듈의 MutableMapping 추상 클래스는 딕셔너리와 같은 매핑 타입을 정의하는 데 사용됩니다. MutableMapping은 Mapping을 상속받아 변경 가능한 매핑 타입의 인터페이스를 정의합니다.

MutableMapping을 활용한 사용자 정의 클래스

MutableMapping을 상속받아 커스터마이즈된 딕셔너리 클래스를 구현할 수 있습니다. 이를 통해 기본 딕셔너리 기능을 확장하거나 새로운 기능을 추가할 수 있습니다.

from collections.abc import MutableMapping

class CustomDict(MutableMapping):
    def __init__(self):
        self._store = {}

    def __getitem__(self, key):
        return self._store[key]

    def __setitem__(self, key, value):
        self._store[key] = value

    def __delitem__(self, key):
        del self._store[key]

    def __iter__(self):
        return iter(self._store)

    def __len__(self):
        return len(self._store)

# CustomDict 사용 예제
custom_dict = CustomDict()
custom_dict['a'] = 1
custom_dict['b'] = 2

print(custom_dict['a'])  # 출력: 1
print(custom_dict)  # 출력: {'a': 1, 'b': 2}

del custom_dict['a']
print(custom_dict)  # 출력: {'b': 2}
print(len(custom_dict))  # 출력: 1

 

CustomDict에 예제 메서드 추가 및 활용

CustomDict 클래스에 예제 메서드를 추가하여 실제로 어떻게 활용할 수 있는지 살펴보겠습니다. 이 예제에서는 increment라는 메서드를 추가하여, 특정 키의 값을 증가시키는 기능을 구현해보겠습니다.

CustomDict 클래스 정의 및 예제 메서드 추가

 

from collections.abc import MutableMapping

class CustomDict(MutableMapping):
    def __init__(self):
        self._store = {}

    def __getitem__(self, key):
        return self._store[key]

    def __setitem__(self, key, value):
        self._store[key] = value

    def __delitem__(self, key):
        del self._store[key]

    def __iter__(self):
        return iter(self._store)

    def __len__(self):
        return len(self._store)

    # 예제 메서드 추가: 특정 키의 값을 증가시키는 메서드
    def increment(self, key, amount=1):
        if key in self._store:
            self._store[key] += amount
        else:
            self._store[key] = amount

# CustomDict 사용 예제
custom_dict = CustomDict()
custom_dict['a'] = 1
custom_dict.increment('a')
custom_dict.increment('b', 5)

print(custom_dict['a'])  # 출력: 2
print(custom_dict['b'])  # 출력: 5
print(custom_dict)  # 출력: {'a': 2, 'b': 5}

 

위 예제에서 CustomDict 클래스에 increment 메서드를 추가하여, 특정 키의 값을 증가시키는 기능을 구현했습니다.

Dictionary에서 비슷하게 구현

기본 dict를 사용하여 비슷한 기능을 구현할 수도 있습니다. 이를 위해 별도의 함수를 정의해보겠습니다.

# 기본 dict를 사용하여 increment 기능을 제공하는 함수
def increment(d, key, amount=1):
    if key in d:
        d[key] += amount
    else:
        d[key] = amount

# dict 사용 예제
basic_dict = {'a': 1}
increment(basic_dict, 'a')
increment(basic_dict, 'b', 5)

print(basic_dict['a'])  # 출력: 2
print(basic_dict['b'])  # 출력: 5
print(basic_dict)  # 출력: {'a': 2, 'b': 5}

CustomDict와 기본 dict를 사용한 구현의 장단점

CustomDict의 장점

  1. 메서드 추가 및 확장 용이:
    • 클래스 메서드로 기능을 구현하면, 객체 지향적인 접근이 가능하고, 상태를 쉽게 관리할 수 있습니다.
    • 메서드를 통해 기능을 캡슐화하여 코드의 재사용성과 유지보수성을 높일 수 있습니다.
  2. 인터페이스 일관성:
    • MutableMapping을 상속받아 딕셔너리와 동일한 인터페이스를 제공하므로, 기존의 딕셔너리 사용 패턴과 호환됩니다.
  3. 추가 기능 구현의 용이성:
    • CustomDict 클래스를 확장하여 새로운 기능을 쉽게 추가할 수 있습니다.

CustomDict의 단점

  1. 복잡성 증가:
    • 기본 dict를 사용하는 것보다 클래스를 정의하고 관리하는 데 더 많은 코드와 복잡성이 필요합니다.
  2. 성능 저하 가능성:
    • 추가된 추상화 계층으로 인해 성능이 약간 저하될 수 있습니다.

기본 dict의 장점

  1. 단순성:
    • 별도의 클래스를 정의하지 않고, 단순한 함수로 기능을 구현할 수 있어 코드가 간결합니다.
    • 기본 dict는 Python의 내장 자료형이므로 추가적인 학습이나 설정 없이 바로 사용할 수 있습니다.
  2. 성능:
    • Python의 기본 dict는 C로 구현되어 있어 매우 빠릅니다.

기본 dict의 단점

  1. 재사용성 및 유지보수성 저하:
    • 기능을 함수로 구현하면, 상태와 기능이 분리되어 있어 재사용성과 유지보수성이 낮아질 수 있습니다.
    • 여러 함수로 기능을 확장하는 경우, 코드의 일관성을 유지하기 어렵습니다.
  2. 객체 지향 프로그래밍의 한계:
    • 객체 지향 프로그래밍의 이점을 활용하지 못하므로, 복잡한 상태 관리나 기능 확장이 어렵습니다.

결론

  • CustomDict: 객체 지향적인 접근으로, 상태와 기능을 캡슐화하여 코드의 재사용성과 유지보수성을 높일 수 있습니다. 복잡한 기능을 확장하는 데 유리하지만, 기본 dict보다 구현과 관리가 더 복잡합니다.
  • 기본 dict: 간단하고 성능이 우수하지만, 복잡한 기능을 확장하거나 유지보수할 때 어려움이 있을 수 있습니다.

두 접근 방식 모두 장단점이 있으므로, 특정 상황과 요구 사항에 따라 적절한 방법을 선택하는 것이 중요합니다.

반응형

'Computer Science > python' 카테고리의 다른 글

동적 속성과 프로퍼티  (0) 2024.08.16
연산자 오버로딩  (0) 2024.07.09
프로토콜과 'abc' 모듈  (0) 2024.06.11
Python 데코레이터  (0) 2024.05.21
seaborn clustermap color label  (0) 2022.05.24

+ Recent posts