La méthode getitem a été ajoutée à Python dans le cadre du protocole des séquences et des mapping. Grâce à cette méthode magique, les collections standards (list, tuple, dict, etc.) prennent en charge l'accès par index, clé et tranche. Dans les classes utilisateur, cette méthode permet aux objets de se comporter "comme des collections".
Sans l'implémentation de getitem, la classe utilisateur ne prend pas en charge l'indexation et l'itération avec for. L'implémentation uniquement pour les index simples n'est pas applicable si l'on veut un fonctionnement complet avec les tranches (slice), et ignorer les variétés d'index entraînera des erreurs.
Implémenter getitem pour prendre en charge à la fois les index et les objets de type slice, en les séparant dans le traitement. Cela permet d'utiliser des objets personnalisés dans les constructions standard de Python (par exemple, pour prendre en charge les tranches your_obj[1:5]).
Exemple de code :
class MyRange: def __init__(self, n): self.n = n def __getitem__(self, item): if isinstance(item, int): # Index individuel if 0 <= item < self.n: return item * 2 raise IndexError('index out of range') elif isinstance(item, slice): # Tranche return [self[i] for i in range(*item.indices(self.n))] else: raise TypeError('Type d'argument invalide : {}'.format(type(item))) mr = MyRange(10) print(mr[3]) # 6 print(mr[2:5]) # [4, 6, 8]
Caractéristiques clés :
L'implémentation uniquement de getitem permet-elle d'assigner des valeurs par index ?
Non. Pour prendre en charge l'assignation (your_obj[i] = value), il faut implémenter setitem. getitem ne répond qu'à la lecture.
Doit-on nécessairement retourner une liste pour une tranche, comme le fait list ?
Non. L'essentiel est de retourner une "séquence" en tenant compte du sens de la classe (on peut retourner le même type ou, par exemple, un tuple). L'important est que cela ait un sens dans le contexte de la tâche.
Pourquoi obtient-on parfois l'erreur TypeError : 'MyClass' object is not subscriptable ?
Ce message apparaît si vous essayez d'exécuter my_obj[0], mais la classe n'implémente pas getitem. Pour que la classe soit subscriptable (prenne en charge []), cette méthode est obligatoire.
Implémenté getitem uniquement pour int, oublié slice. Toute tentative my_obj[2:5] entraîne une TypeError et échoue tout l'algorithme de traitement des collections.
Avantages :
Inconvénients :
getitem est implémenté avec un traitement séparé pour slice et int. Les tranches et les index fonctionnent, les méthodes list(), map(), et l'itération sont prises en charge sans efforts supplémentaires.
Avantages :
Inconvénients :