복붙노트

[PYTHON] 파이썬에서리스트 객체를 상속하고 확장하는 방법은?

PYTHON

파이썬에서리스트 객체를 상속하고 확장하는 방법은?

나는 파이썬리스트 객체를 사용하는데 관심이 있지만 약간 변경된 기능을 사용한다. 특히, 목록이 0 인덱싱 대신 1 인덱싱되도록하고 싶습니다. 예 :

>> mylist = MyList()
>> mylist.extend([1,2,3,4,5])
>> print mylist[1]

출력은 다음과 같아야합니다. 1

그러나 이것을 수행하기 위해 __getitem __ () 및 __setitem __ () 메소드를 변경했을 때 RuntimeError : maximum recursion depth exceeded 오류가 발생했습니다. 나는이 방법으로 많은 주위를 어지럽 혔지 만 이것은 기본적으로 내가 거기에있는 것입니다 :

class MyList(list):
    def __getitem__(self, key):
        return self[key-1]
    def __setitem__(self, key, item):
        self[key-1] = item

문제는 자기 [key-1] 자체가 정의하고있는 것과 같은 메서드를 호출한다는 것입니다. 그렇다면 어떻게 MyList () 메서드 대신 list () 메서드를 사용하게합니까? 나는 자기 [key-1] 대신에 super [key-1]을 사용하려했지만 불만을 야기했다. TypeError : 'type'객체는 구독 취소 가능하다.

어떤 아이디어? 또한 이것에 대한 좋은 튜토리얼을 가르쳐 주시면 좋을 것입니다!

감사!

해결법

  1. ==============================

    1.super () 함수를 사용하여 기본 클래스의 메서드를 호출하거나 메서드를 직접 호출합니다.

    super () 함수를 사용하여 기본 클래스의 메서드를 호출하거나 메서드를 직접 호출합니다.

    class MyList(list):
        def __getitem__(self, key):
            return list.__getitem__(self, key-1)
    

    또는

    class MyList(list):
        def __getitem__(self, key):
            return super(MyList, self).__getitem__(key-1)
    

    그러나 다른 목록 방법의 동작은 변경되지 않습니다. 예를 들어 인덱스는 변경되지 않고 예기치 않은 결과가 발생할 수 있습니다.

    numbers = MyList()
    numbers.append("one")
    numbers.append("two")
    
    print numbers.index('one')
    >>> 1
    
    print numbers[numbers.index('one')]
    >>> 'two'
    
  2. ==============================

    2.대신, 같은 방법으로 정수를 서브 클래스 화하여 모든 숫자를 설정 한 값에서 1을 뺀 값으로 정의하십시오. Voila.

    대신, 같은 방법으로 정수를 서브 클래스 화하여 모든 숫자를 설정 한 값에서 1을 뺀 값으로 정의하십시오. Voila.

    미안, 나는해야했다. 마이크로 소프트가 어둠을 표준으로 규정한다는 농담처럼.

  3. ==============================

    3.추상 클래스 인 collections.MutableSequence로부터 상속받은 클래스를 생성하여 Liskov 대체 원칙을 위반하는 것을 피할 수 있습니다. 다음과 같이 보일 것입니다 :

    추상 클래스 인 collections.MutableSequence로부터 상속받은 클래스를 생성하여 Liskov 대체 원칙을 위반하는 것을 피할 수 있습니다. 다음과 같이 보일 것입니다 :

    class MyList(collections.MutableSequence):
    def __init__(self, l=[]):
        if type(l) is not list:
            raise ValueError()
    
        self._inner_list = l
    
    def __len__(self):
        return len(self._inner_list)
    
    def __delitem__(self, index):
        self._inner_list.__delitem__(index - 1)
    
    def insert(self, index, value):
        self._inner_list.insert(index - 1, value)
    
    def __setitem__(self, index, value):
        self._inner_list.__setitem__(index - 1, value)
    
    def __getitem__(self, index):
        return self._inner_list.__getitem__(index - 1)
    

    여기에는 하나의 문제가 있습니다 (더있을 지 모르지만). 다음과 같이 새 목록의 색인을 생성하는 경우 :

    l = MyList()
    l[0]
    

    당신은 실제로 전화 할 것입니다 :

    self._inner_list[-1]
    

    그러면 마지막 요소가 생깁니다. 따라서 목록에서 해당 기능을 사용하려면 메서드에서 추가 검사를 수행하고 역 색인 생성을 유지해야합니다.

    편집하다:

    다음은 새로운 코드입니다. 아무 문제가 없어야한다고 생각합니다.

    def indexing_decorator(func):
    
        def decorated(self, index, *args):
            if index == 0:
                raise IndexError('Indices start from 1')
            elif index > 0:
                index -= 1
    
            return func(self, index, *args)
    
        return decorated
    
    
    class MyList(collections.MutableSequence):
        def __init__(self):
            self._inner_list = list()
    
        def __len__(self):
            return len(self._inner_list)
    
        @indexing_decorator
        def __delitem__(self, index):
            self._inner_list.__delitem__(index)
    
        @indexing_decorator
        def insert(self, index, value):
            self._inner_list.insert(index, value)
    
        @indexing_decorator
        def __setitem__(self, index, value):
            self._inner_list.__setitem__(index, value)
    
        @indexing_decorator
        def __getitem__(self, index):
            return self._inner_list.__getitem__(index)
    
        def append(self, value):
            self.insert(len(self) + 1, value)
    
  4. ==============================

    4.

    class ListExt(list):
        def extendX(self, l):
            if l:
                self.extend(l)
    
  5. from https://stackoverflow.com/questions/4093029/how-to-inherit-and-extend-a-list-object-in-python by cc-by-sa and MIT license