Python __index__ Method
Last modified April 8, 2025
This comprehensive guide explores Python's __index__ method, the
special method used for integer conversion in indexing operations. We'll cover
basic usage, sequence protocols, custom number types, and practical examples.
Basic Definitions
The __index__ method is a special method that returns an integer
representation of an object. It's used when an object needs to be converted to
an integer for indexing operations.
Key characteristics: it must return an integer, is called by operator.index(),
and is used in slicing and indexing operations. It provides lossless integer
conversion unlike __int__.
Basic __index__ Implementation
Here's a simple implementation showing how __index__ enables objects
to be used as indices in sequences like lists or tuples.
class MyIndex:
def __init__(self, value):
self.value = value
def __index__(self):
return self.value
idx = MyIndex(3)
my_list = [10, 20, 30, 40, 50]
print(my_list[idx]) # Output: 40
This example shows how an object with __index__ can be used directly
as a list index. The method returns the stored integer value when needed for
indexing.
The __index__ method is called implicitly when the object is used
in an indexing context, converting it to a suitable integer index.
Using __index__ with Slicing
__index__ is also used in slice operations, allowing custom objects
to be used as slice indices.
class SliceIndex:
def __init__(self, value):
self.value = value
def __index__(self):
return self.value
start = SliceIndex(1)
stop = SliceIndex(4)
my_list = [0, 10, 20, 30, 40, 50]
print(my_list[start:stop]) # Output: [10, 20, 30]
This demonstrates how objects with __index__ can be used in slice
notation. Both start and stop positions are converted to integers automatically.
The slice operation calls __index__ on both slice bounds before
performing the slice, enabling custom index types in slicing.
Difference Between __index__ and __int__
While similar, __index__ and __int__ serve different
purposes. __index__ is specifically for lossless integer conversion.
class Number:
def __init__(self, value):
self.value = value
def __index__(self):
print("__index__ called")
return self.value
def __int__(self):
print("__int__ called")
return self.value + 0.5 # Not a pure integer
num = Number(5)
print(operator.index(num)) # Uses __index__
print(int(num)) # Uses __int__
This shows the different behavior between the two methods. __index__
must return an exact integer, while __int__ can perform conversions.
__index__ is preferred in indexing contexts as it guarantees proper
integer values, while __int__ is for general number conversion.
Custom Number Types with __index__
__index__ allows custom number types to integrate with Python's
indexing system, making them behave like built-in integers in sequences.
class BinaryNumber:
def __init__(self, binary_str):
self.binary = binary_str
def __index__(self):
return int(self.binary, 2)
binary = BinaryNumber('1101') # 13 in decimal
my_list = [i*10 for i in range(20)]
print(my_list[binary]) # Output: 130
print(operator.index(binary)) # Output: 13
This binary number class converts its value to an integer when used as an index.
The __index__ method handles the binary-to-decimal conversion.
This pattern is useful for custom numeric types that need to work with Python's sequence protocols while maintaining their own internal representation.
Using __index__ with NumPy Arrays
NumPy arrays and other scientific Python libraries use __index__ for
array indexing, allowing custom index types to work with these libraries.
import numpy as np
class ArrayIndex:
def __init__(self, value):
self.value = value
def __index__(self):
return self.value * 2 # Custom index transformation
arr = np.arange(0, 100, 10) # [0, 10, 20, ..., 90]
idx = ArrayIndex(3)
print(arr[idx]) # Output: 60 (uses value 6 as index)
This example shows how a custom index type can be used with NumPy arrays. The
__index__ method transforms the index value before array access.
NumPy calls __index__ when processing array indices, enabling
custom index transformations while maintaining array access performance.
Best Practices
- Return integers only:
__index__must return an integer - Keep it lossless: Conversion should preserve all information
- Prefer over __int__ for indexing: Use
__index__in sequence contexts - Implement for custom sequences: If your class needs integer conversion
- Consider performance:
__index__should be fast for indexing
Source References
Author
List all Python tutorials.