O que exatamente significa "iterável" em Python?

Primeiro quero esclarecer, NÃO estou perguntando o que é "iterador".

É assim que o termo "iterável" é definido no Pythondoc:

iterável
Um objeto capaz de retornar seus membros um de cada vez. Exemplos de iteráveis incluem todos os tipos de sequência (como lista, str e tupla) e alguns tipos que não são de sequência, como dict, objetos de arquivo e objetos de qualquer classe, definidos com um__iter __ () ou __getitem __ () método. Os iteráveis podem ser usados em um loop for e em muitos outros lugares em que uma sequência é necessária (zip (), mapa (), ...). Quando um objeto iterável é passado como argumento para a função interna iter (), ele retorna um iterador para o objeto. Esse iterador é bom para uma passagem sobre o conjunto de valores. Ao usar iterables, geralmente não é necessário chamar iter () ou lidar com objetos iteradores. A instrução for faz isso automaticamente para você, criando uma variável temporária sem nome para manter o iterador pela duração do loop. Consulte também iterador, sequência e gerador.

Comooutras pessoas sugeriram, usandoisinstance(e, collections.Iterable) é a maneira mais pitônica de verificar se um objeto é iterável.
Então eu fiz alguns testes com o Python 3.4.3:

from collections.abc import Iterable

class MyTrain:
    def __getitem__(self, index):
        if index > 3:
            raise IndexError("that's enough!")

        return index

for name in MyTrain():
    print(name)  # 0, 1, 2, 3

print(isinstance(MyTrain(), Iterable))  # False

O resultado é bastante estranho:MyTrain definiu__getitem__ , mas não é considerado um objeto iterável, sem mencionar que é capaz de retornar um número de cada vez.

Então eu removi__getitem__ e adicionou o__iter__ método:

from collections.abc import Iterable

class MyTrain:    
    def __iter__(self):
        print("__iter__ called")
        pass

print(isinstance(MyTrain(), Iterable))  # True

for name in MyTrain():
    print(name)  # TypeError: iter() returned non-iterator of type 'NoneType'

Agora é considerado como um objeto iterável "verdadeiro", apesar de não poder produzir nada durante a iteração.

Entendi mal alguma coisa ou a documentação está incorreta?

questionAnswers(3)

yourAnswerToTheQuestion