ProgramingTip

클래스에 __getitem__을 정의하면 반복 할 수있는 이유는 무엇입니까?

bestdevel 2020. 12. 14. 20:40
반응형

클래스에 __getitem__을 정의하면 반복 할 수있는 이유는 무엇입니까?


클래스에서 __getitem__을 정의하면 반복 할 수있는 이유는 무엇입니까?

예를 들어 다음과 같이 작성하면

class b:
  def __getitem__(self, k):
    return k

cb = b()

for k in cb:
  print k

출력을 얻습니다.

0
1
2
3
4
5
6
7
8
...

"for k in cb :"에서 오류가 반환 될 것으로 예상됩니다.


반복자를 정의하는 PEP234를 살펴보면 다음과 같습니다 .

1. An object can be iterated over with "for" if it implements
   __iter__() or __getitem__().

2. An object can function as an iterator if it implements next().

에 대한 반복의 지원은 __getitem__PEP234가 반복을 기본 개념으로 허용 할 때보 다 많은 전환을 "레거시 기능"으로 볼 수 있습니다. 정수 0, 1, & c __iter____getitem__받아들이지 않는 클래스에만 적용이 IndexError적용가 너무 많은면 (만약 있음) 발생합니다. 일반적으로 __iter__나타나기 전에 코딩 된 "시퀀스"클래스입니다 (이런 방식으로 새 클래스를 코딩하는 것을 막을 수는 없지만).

개인적으로 나는 새로운 코드 에서이 코드에 의존하지 않을 것입니다. 비록 더 이상 사용되지 않거나 사라지지는 않지만 (파이썬 3에서도 잘 작동합니다) 스타일과 취향의 문제 일뿐입니다 ( "명시적인 것이 암시적인 것보다 낫다"그래서 나는 __getitem__그것을 암시 적 으로 지원하는 을 구석으로보다 명시 적으로 반복성을 지원하고 싶지만, 큰 것은 아닙니다.)


__getitem__반복자 프로토콜보다 이전이며 과거에는 일을 반복 할 수 있는

유일한 방법. 계속 반복 방법으로 계속 지원됩니다. 기본적으로 반복을위한 프로토콜은 다음과 가변합니다.

  1. __iter__방법을 확인하십시오 . 존재하는 경우 새 반복 프로토콜을 사용하십시오.

  2. 그렇지 않으면 __getitem__IndexError 발생할 때까지가 연속적으로 더 큰 정수 값으로 호출 해보 십시오.

(2)이 작업을 수행하는 유일한 방법이 반복을 지원하는 데 데리고 있다는 것보다 더 많은 것을 수행하는 것을 수행합니다. 반복을 지원하기 위해 액세스를 지원해야, 파일이나 네트워크 스트림과 같은 경우 훨씬 더 비 저장지만 뒤로 이동 모든 것을 저장해야합니다. __iter__임의 액세스없이 반복을 허용했지만 임의 액세스는 일반적으로 반복을 허용하고 이전 버전과의 회의를 깨는 것은 나쁘기 때문에 __getitem__여전히 지원됩니다.


__getitem__반복을 포함하여 특성에 특수 동작을 추가 하는 것과 같은 특수 메서드 .

http://docs.python.org/reference/datamodel.html#object. getitem

"for 루프는 잘못된 인덱스에 대해 IndexError가 발생하여 시퀀스 끝을 올바르게 감지 할 수있을 것으로 예상합니다."

IndexError를 발생시켜 시퀀스의 끝을 알립니다.

코드는 기본적으로 다음과 같습니다.

i = 0
while True:
    try:
        yield object[i]
        i += 1
    except IndexError:
        break

객체는 for 루프에서 반복하는 것입니다.


이것은 역사적 이유 때문입니다. Python 2.2 이전에는 __getitem__이 for 루프로 반복 할 수있는 클래스를 만드는 유일한 방법이었습니다. 2.2에서는 __iter__ 프로토콜이 추가되었지만 이전 버전과의 호환성을 유지하기 위해 __getitem__은 여전히 ​​for 루프에서 작동합니다.


때문에 cb[0]동일하다 cb.__getitem__(0). 이것에 대한 파이썬 문서참조하십시오 .

참고 URL : https://stackoverflow.com/questions/926574/why-does-defining-getitem-on-a-class-make-it-iterable-in-python

반응형