Eu escrevi um objeto de recipiente personalizado.
De acordo com esta página , preciso implementar este método em meu objeto:
__iter__(self)
No entanto, ao seguir o link para Tipos de Iterador no manual de referência do Python, não há exemplos fornecidos de como implementar o seu próprio.
Alguém pode postar um snippet (ou link para um recurso), que mostra como fazer isso?
O contêiner que estou escrevendo é um mapa (ou seja, armazena valores por chaves exclusivas). dictos podem ser iterados assim:
for k, v in mydict.items()
Nesse caso, preciso retornar dois elementos (uma tupla?) No iterador. Ainda não está claro como implementar tal iterador (apesar das várias respostas que foram gentilmente fornecidas). Alguém poderia lançar mais luz sobre como implementar um iterador para um objeto recipiente semelhante a um mapa? (ou seja, uma classe personalizada que atua como um dicionário)?
some_list
tiverem sido produzidos.some_list
se esgotar.StopIteration
é gerado automaticamente pelo Python quando a função geradora retorna, seja por você chamando explicitamentereturn
ou alcançando o final da função (que, como todas as funções, tem umreturn None
final implícito ). Aumentar explicitamenteStopIteration
não é necessário e a partir do Python 3.5 realmente não funcionará (consulte PEP 479 ): assim como os geradores se transformamreturn
emStopIteration
, eles se tornam explícitosraise StopIteration
em aRuntimeError
.Outra opção é herdar da classe base abstrata apropriada do módulo `coleções como documentado aqui .
Caso o contêiner seja seu próprio iterador, você pode herdar de
collections.Iterator
. Você só precisa implementar onext
método então.Um exemplo é:
Enquanto você está olhando para o
collections
módulo, considere herdar deSequence
,Mapping
ou outra classe base abstrata, se for mais apropriado. Aqui está um exemplo para umaSequence
subclasse:NB : Obrigado a Glenn Maynard por chamar minha atenção para a necessidade de esclarecer a diferença entre iteradores por um lado e contêineres que são iteráveis em vez de iteradores por outro.
fonte
normalmente
__iter__()
apenas retorna self se você já definiu o método next () (objeto gerador):aqui está um exemplo fictício de um gerador:
mas
__iter__()
também pode ser usado assim: http://mail.python.org/pipermail/tutor/2006-January/044455.htmlfonte
Se o seu objeto contém um conjunto de dados ao qual deseja vincular o iter do seu objeto, você pode trapacear e fazer o seguinte:
fonte
hasattr
, usetry/except AttributeError
A "interface iterável" em python consiste em dois métodos
__next__()
e__iter__()
. A__next__
função é a mais importante, pois define o comportamento do iterador - ou seja, a função determina qual valor deve ser retornado em seguida. O__iter__()
método é usado para redefinir o ponto de partida da iteração. Freqüentemente, você descobrirá que__iter__()
só pode retornar self quando__init__()
for usado para definir o ponto de partida.Consulte o código a seguir para definir uma Class Reverse que implementa a "interface iterável" e define um iterador sobre qualquer instância de qualquer classe de sequência. O
__next__()
método começa no final da sequência e retorna valores na ordem inversa da sequência. Observe que as instâncias de uma classe que implementa a "interface de sequência" devem definir um__len__()
e um__getitem__()
método.fonte
Para responder à pergunta sobre mapeamentos : seu fornecido
__iter__
deve iterar sobre as chaves do mapeamento. A seguir está um exemplo simples que cria um mapeamentox -> x * x
e funciona em Python3 estendendo o mapeamento ABC.fonte
Caso você não queira herdar
dict
como outros sugeriram, aqui está uma resposta direta à pergunta sobre como implementar__iter__
um exemplo bruto de um dicionário personalizado:Isso usa um gerador, que é bem descrito aqui .
Já que estamos herdando de
Mapping
, você também precisa implementar__getitem__
e__len__
:fonte
Uma opção que pode funcionar em alguns casos é fazer com que sua classe personalizada herde de
dict
. Esta parece ser uma escolha lógica se agir como um ditado; talvez devesse ser um ditado. Dessa forma, você obtém uma iteração do tipo dict gratuitamente.Resultado:
fonte
exemplo para herdar de dict, modifique a sua
iter
, por exemplo, tecla pular2
quando em loop forfonte