CDict.py

from collections import OrderedDict

class CDict(dict):

    def __init__(self, dict={}):
        super().__init__(dict)
        self.orderedDict = OrderedDict(self)

    def __setitem__(self, key, value):
        super().__setitem__(key, value)
        self.orderedDict = OrderedDict(self)

    def __delitem__(self, key):
        super().__delitem__(key)
        self.orderedDict = OrderedDict(self)

    def clear(self):
        self.orderedDict = OrderedDict({})
        super().clear()

    def index(self, key):
        return list(self.orderedDict).index(key)

    def insert(self, index, key, value):
        l = list((self.orderedDict).items())
        l.insert(index, (key, value))

        self.clear()
        self.orderedDict = OrderedDict(l)

        self.update(dict(self.orderedDict))
  1. __init__ method
    내장함수인 dict 클래스를 상속한 CDict 클래스에서는 dict와 동시에 index와 insert메서드를 위한 orderedDict를 프로퍼티로써 항상 지니도록 입력해줍니다. 이때 dict와 orderdict의 정합성을 맞춰주는 것이 조금 귀찮습니다.
     
    생성자에 파라미터로 dict를 넣으면 초기값이 되도록 super().__init__(dict)도 추가해줍시다.

  2. __setitem__ method
    dict객체를 idle에서 분석해보면 아래와 같은 내장 매서드를 갖고 있는 것을 확인할 수 있습니다.

    > dir({"a":1})
    > ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', 
    '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', 
    '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', 
    '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', 
    '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 
    'popitem', 'setdefault', 'update', 'values']

    __init__ 에서도 언급했듯 dict와 orderedDict의 정합성을 맞춰주어야 하기 때문에, dict 내부의 데이터를 수정하는 메서드와 관련된 __delattr__ __delitem__ clear __setitem__ 등의 메서드에 orderedDict을 동시에 수정해주는 코드를 넣어 커스터마이징 해줍니다. 저는 귀찮아서 pop관련 함수는 커스터마이징 하지 않았지만, orderedDict의 정합성을 맞추기위해서는 반드시 커스터마이징 해주어야 합니다.
     
    내장함수를 오버로드하면 되므로 super()을 사용해 기존 dict 클래스의 메서드는 그대로 사용하면서, orderedDict의 정합성을 맞추는 코드를 추가합니다.

  3. insert method
    파라미터로는 index와 새롭게 추가할 dict의 key와 value를 받는 것으로 해둡니다. 이때 ordereDict를 활용해 inserting을 하므로, 새로운 데이터가 추가된 ordereDict에 맞추어 기존의 dict의 정합성을 맞춰주어야 합니다. 이를 위해 dict를 clear -> dict에 ordereDict 업데이트 의 순서로 진행해줍니다.

test.py

from util.CDict import CDict

cd = CDict()
cd['a'] = 1
print(cd.orderedDict)
# OrderedDict[('a', 1)]

cd['b'] = 2
print(cd.orderedDict)
# OrderedDict[('a', 1), ('b', 2)]

cd['c'] = 3
print(cd.orderedDict)
# OrderedDict[('a', 1), ('b', 2), ('c', 3)]

cd.__delitem__('c')
print(cd.orderedDict)
# OrderedDict[('a', 1), ('b', 2)]

# index method 확인
index = cd.index('b')
print(cd.orderedDict)

# insert method 확인
cd.insert(index, 'd', 4)
print(cd.orderedDict)
# OrderedDict[('a', 1), ('d', 4), ('b', 2)]

cd.clear()
print(cd.orderedDict)
# OrderedDict()

참고

'C Lang > Python Program Diary' 카테고리의 다른 글

파이선 Selenium으로 스크래핑 기초  (0) 2021.01.21
pyenv로 python인스톨 후 pipenv로 가상환경 관리하기  (0) 2020.02.06
dict를 sorting하기  (0) 2020.01.09
로그 가이드라인  (0) 2019.11.21
pyenv 정리  (0) 2019.11.18

+ Recent posts