Python >> Tutoriel Python >  >> Python

Méthode magique Python __iter__()

Syntaxe

object.__iter__(self)

Le Python __iter__ La méthode renvoie un objet itérateur. Un objet itérateur est un objet qui implémente le __next__() méthode dunder qui renvoie l'élément suivant de l'objet itérable et lève un StopIteration erreur si l'itération est faite.

Formellement, le __iter__() la méthode implémente le iter() intégré fonction. Par exemple, si vous appelez iter(x) un objet x , Python appelle en interne x.__iter__() pour déterminer l'objet itérable associé à x .

Nous appelons cela une "méthode Dunder" pour "D ouble Sous Méthode de score" (également appelée "méthode magique" ). Pour obtenir une liste de toutes les méthodes de dunder avec des explications, consultez notre article sur la feuille de triche de dunder sur ce blog.

Itérer en arrière-plan()

iter() intégré de Python La fonction renvoie un itérateur pour l'objet donné. Par exemple, iter([1, 2, 3]) crée un itérateur pour la liste [1, 2, 3] .

Vous pouvez ensuite itérer sur tous les éléments de l'itérateur, un élément à la fois, dans une boucle for ou while telle que :for x in iter([1, 2, 3]) .

Avant d'en savoir plus sur le __iter__() méthode dunder, regardons un iter() de base exemple :

customers = ['Alice', 'Bob', 'Carl', 'Dave', 'Elena', 'Frank']
iterator = iter(customers)

print(next(iterator))
print(next(iterator))

for x in iterator:
    print(x)

Vous pouvez voir une explication et le résultat de ceci sur notre tutoriel de blog détaillé ici :

  • Python iter() — Un guide illustré simple avec vidéo

Exemple personnalisé __iter__()

Dans l'exemple suivant, vous créez une classe personnalisée Data et écrasez le __init__() , __iter__() , et __next__() méthodes afin que vous puissiez créer votre propre itérateur sur un Data objet.

class Data:
    def __init__(self, data):
        self.data = data # an iterable

    def __iter__(self):
        self.current_index = 0
        return self

    def __next__(self):
        if self.current_index < len(self.data):
            x = self.data[self.current_index]
            self.current_index += 1
            return x
        raise StopIteration
  • __init__() initialise l'attribut de données qui devrait être un itérable.
  • __iter__() renvoie l'objet itérateur — celui qui implémente le __next__() méthode. Dans notre cas, il s'agit de l'objet Data sur lequel il s'appelle lui-même. Nous initialisons current_index avec zéro, nous commençons donc l'itération avec le premier index de data .
  • __next__() renvoie la valeur suivante après une itération. On incrémente le current_index attribut pour garder une trace de l'index actuel de l'élément dans data .

Créons un Data objet d et un itérateur sur l'objet de données en utilisant le iter() intégré fonction (qui appelle en interne __iter__() )—et commencez à itérer sur l'objet en utilisant le next() intégré fonction (qui appelle en interne __next__() ):

d = Data([1, 'Alice', 42, 'finxter'])

# Create an iterator
iterator = iter(d)

# Dynamically generate the next values - iterate!
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))

Le résultat est le suivant :les quatre premiers appels génèrent les éléments attendus de l'attribut de données, c'est-à-dire 1 , 'Alice' , 42 , et 'finxter' . Le cinquième appel de next() donne un StopIteration erreur car nous avons fini d'itérer sur tous les éléments.

1
Alice
42
finxter
Traceback (most recent call last):
  File "C:\Users\xcent\Desktop\code.py", line 34, in <module>
    print(next(iterator))
  File "C:\Users\xcent\Desktop\code.py", line 14, in __next__
    raise StopIteration
StopIteration

Si vous n'aviez pas défini le __iter__() méthode, Python aurait généré une erreur :

TypeError :l'objet '...' n'est pas itérable

Si vous appelez le iter(x) sur un objet sur lequel le x.__iter__() la méthode dunder n'est pas définie, Python lèvera un TypeError: '...' object is not iterable .

Pour corriger cette erreur, définissez simplement le __iter__() méthode dans la définition de classe avant d'appeler iter() sur un objet et assurez-vous que __iter__() renvoie un objet itérateur sur lequel la méthode dunder __next__() est défini !

Voici un exemple :

class Data:
    def __init__(self, data):
        self.data = data # an iterable

    
        
d = Data([1, 'Alice', 42, 'finxter'])

# Create an iterator
iterator = iter(d)

Voici le message d'erreur :

Traceback (most recent call last):
  File "C:\Users\xcent\Desktop\code.py", line 10, in <module>
    iterator = iter(d)
TypeError: 'Data' object is not iterable

Références :

  • https://docs.python.org/3/reference/datamodel.html