[python] 파이썬 __getitem__ 및 연산자에서 이상한 동작이 발생합니다.

다음 동작을 설명하는 내용 :

class Foo:
    def __getitem__(self, item):
        print("?")
        return 1

f = Foo()

1 in f  # prints one ? and returns True

5 in f  # prints ? forever until you raise a Keyboard Exception

# Edit: eventually this fails with OverflowError: iter index too large



답변

객체에 __contains__구현 이 없으면 in기본적으로 다음과 같이 작동하는 기본값으로 돌아갑니다.

def default__contains__(self, element):
    for thing in self:
        if thing == element:
            return True
    return False

그리고 객체에 __iter__구현 이 없으면 for기본적으로 다음과 같이 작동하는 기본값으로 돌아갑니다.

def default__iter__(self):
    i = 0
    try:
        while True:
            yield self[i]
            i += 1
    except IndexError:
        pass

이 기본값은 객체가 시퀀스가 ​​아닌 경우에도 사용됩니다.

귀하 1 in f5 in f테스트에 대한 기본 폴백 (fallback)를 사용 in하고 for관찰 된 행동에지도. 즉시 1 in f찾지 1__getitem__결코 반환하지 5않으므로 5 in f영원히 실행됩니다.

(실제로 Python의 참조 구현에서 기본 __iter__폴백은 인덱스를 C 유형의 type 변수 유형 Py_ssize_t으로 저장하므로 오래 기다리면 해당 변수가 최대치가되고 Python에서 OverflowError가 발생 합니다. 32 비트 Python 빌드에 있어야합니다. 컴퓨터는 64 비트 Python에서 그 누구도 칠 수있을 정도로 오래 존재하지 않았습니다.)


답변