4.4. Classes étendues

Dans ce chapitre, nous aborderons les différentes techniques qui permettent de définir des classes ayant un comportement spécifique.

4.4.1. Itérateurs

4.4.1.1. Introduction

Un itérateur est un objet qui peut être parcouru par une boucle for. De nombreux objets Python sont en réalités des itérateurs, et leur utilisation permet de simplifier d’une manière élégante le code. De plus, les itérateurs permettent de gagner en performance : en effet, les éléments de ces derniers ne sont évalués que lorsqu’ils sont nécessaires et utiles. Ainsi, contraitement à une séquence qui est gardée toute entière en mémoire (ce qui peut réduire à grande consommation de mémoire), les itérateurs prennent peu de place. Enfin, les itérateurs peuvent être “infinis”.

De nombreuses fonctions, comme map(), sum() ou encore max(), acceptent des itérateurs en argument.

Les itérateurs les plus basiques sont les tuples et les listes :

>>> for i in (1, 2):
...     print(i)
1
2
>>> for i in ['a', 'b']:
...     print(i)
a
b

Les dictionnaires eux aussi sont des itérateurs, ce qui permet d’écrire

>>> dic = {'a': 1, 'b': 2}
>>> for key in dic:
...     print(key)
a
b

bien qu’une idée plus intuive aurait pu être d’itérer sur la liste des clés en utilisant la méthode keys() (qui retourne désormais aussi un itérateur depuis la version 3) :

>>> for key in dic.keys():
...     print(key)
a
b

Les fichiers eux-mêmes sont des itérateurs : les syntaxes for line in f et for line in f.readlines() ont le même effet, bien que la première soit plus efficace.

La fonction iter() permet de transformer un objet en itérateur, tandis que next() permet d’obtenir l’élément suivant.

4.4.1.2. Implémentation

Une classe peut devenir un itérateur à condition d’implémenter les deux méthodes __iter__ et __next__.

Comme exemple, construisons une classe qui prend en argument une séquence et, qui, lorsque utilisée en tant qu’itérateur, retourne les éléments de cette séquence en ordre inverse :

class Reverse:
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

L’exception StopIteration permet d’indiquer que l’itération est terminée et que la boucle doit s’arrêter. Cette exception est automatiquement interceptée par la boucle for.

>>> for char in Reverse('Jour'):
...     print(char)
r
u
o
J

4.4.1.3. Module itertools

Ce module contient de nombreuses fonctions utiles pour travailler avec des itérateurs. Citons par exemple la fonction chain() qui permet de “coller” deux itérateurs.

4.4.2. Exercices

  1. Écrire une classe qui permette de représenter un tableau circulaire, c’est à dire que lorsqu’il est parcouru jusqu’à la fin, on revienne au début. Par exemple, si on prend la séquence (1, 2, 3), alors cinq appels à next() donneront successivement : 1, 2, 3, 1, 2.

Table des matières

Sujet précédent

4.3. Système

Sujet suivant

4.5. Persistance

Cette page