ProgrammingPython Library Developer

How does the __getitem__ method work in Python, why should it be implemented and what should be considered when handling slices?

Pass interviews with Hintsage AI assistant

Answer.

Background

The getitem method was added to Python as part of the sequence and mapping protocol. With this magic method, standard collections (list, tuple, dict, etc.) support access by index, key, and slice. In user-defined classes, this method allows objects to behave "like collections".

Problem

Without the implementation of getitem, a user-defined class does not support indexing and iteration using for. Implementation only for simple indices is not applicable if we want full functionality with slices, and ignoring variations of the index will lead to errors.

Solution

Implement getitem to support both indices and slice objects, separating their handling. This allows user-defined objects to be used in standard Python constructs (for example, to support slices like your_obj[1:5]).

Code example:

class MyRange: def __init__(self, n): self.n = n def __getitem__(self, item): if isinstance(item, int): # Individual index if 0 <= item < self.n: return item * 2 raise IndexError('index out of range') elif isinstance(item, slice): # Slice return [self[i] for i in range(*item.indices(self.n))] else: raise TypeError('Invalid argument type: {}'.format(type(item))) mr = MyRange(10) print(mr[3]) # 6 print(mr[2:5]) # [4, 6, 8]

Key features:

  • getitem is the foundation of the sequence and iterable protocol
  • To support slices, slice should be handled separately
  • IndexError and TypeError exceptions are needed for standard functions to work correctly (e.g., list(), for)

Trick questions.

Does implementing only getitem allow for assigning values by index?

No. To support assignment (your_obj[i] = value), setitem must be implemented. getitem is only responsible for reading.

Should getitem always return a list for slices, like list?

No. The main thing is to return a "sequence" according to the meaning of the class (you can return the same type or, for example, a tuple). The important thing is that it makes sense in the context of the task.

Why does the error TypeError: 'MyClass' object is not subscriptable sometimes occur?

This message appears if you try to execute my_obj[0], and the class does not implement getitem. For the class to be subscriptable (supporting []), this method is mandatory.

Typical mistakes and anti-patterns

  • Only checking int, ignoring slice: slices always raise an error
  • Returning the wrong type (e.g., None for slices instead of a sequence)
  • Not raising IndexError, causing the for loop to behave incorrectly

Real-life example

Negative case

Implemented getitem only for int, forgetting about slice. Any attempt my_obj[2:5] leads to TypeError and failure of the entire collection processing algorithm.

Pros:

  • Simplicity

Cons:

  • Slices are not supported, code is incompatible with most standard constructs

Positive case

getitem is implemented with separate handling of slice and int. Slices and indices work, methods list(), map(), and iteration are supported without additional effort.

Pros:

  • Class is compatible with standard Python tools
  • Easily extendable for any index types (tuple, str for matrices, etc.)

Cons:

  • Implementation requires slightly more code and testing