El método getitem fue añadido a Python como parte del protocolo de secuencias y mapeos. Con este método mágico, las colecciones estándar (list, tuple, dict, etc.) soportan acceso por índice, clave y corte. En las clases personalizadas, este método permite que los objetos se comporten "como colecciones".
Sin la implementación de getitem, la clase personalizada no soporta la indexación y la iteración por for. La implementación solo para índices simples no es aplicable si queremos un funcionamiento completo con cortes (slice), y la ignorancia de las variaciones de índices llevará a errores.
Implementar getitem para soportar tanto índices como objetos del tipo slice, separándolos en el procesamiento. Esto permite usar objetos personalizados en las construcciones estándar de Python (por ejemplo, para soportar cortes your_obj[1:5]).
Ejemplo de código:
class MyRange: def __init__(self, n): self.n = n def __getitem__(self, item): if isinstance(item, int): # Índice individual if 0 <= item < self.n: return item * 2 raise IndexError('índice fuera de rango') elif isinstance(item, slice): # Corte return [self[i] for i in range(*item.indices(self.n))] else: raise TypeError('Tipo de argumento no válido: {}'.format(type(item))) mr = MyRange(10) print(mr[3]) # 6 print(mr[2:5]) # [4, 6, 8]
Características clave:
¿Proporciona la implementación solo de getitem la posibilidad de asignar valores por índice?
No. Para soportar la asignación (your_obj[i] = value) es necesario implementar setitem. getitem solo se encarga de la lectura.
¿Debería getitem necesariamente devolver una lista en el corte, como lo hace list?
No. Lo principal es devolver una "secuencia" teniendo en cuenta el significado de la clase (se puede devolver el mismo tipo o, por ejemplo, un tuple). Lo importante es que tenga sentido en el contexto de la tarea.
¿Por qué a veces aparece el error TypeError: 'MyClass' object is not subscriptable?
Este mensaje aparece si intentas ejecutar my_obj[0] y la clase no implementa getitem. Para que la clase sea subscriptable (soportara []), este método es obligatorio.
Se implementó getitem solo para int, se olvidaron del slice. Cualquier intento de my_obj[2:5] lleva a TypeError y falla todo el algoritmo de procesamiento de colecciones.
Ventajas:
Desventajas:
getitem implementado con un procesamiento separado para slice e int. Los cortes e índices funcionan, los métodos list(), map(), y la iteración se soportan sin esfuerzos adicionales.
Ventajas:
Desventajas: