ZetCode

Python __index__ 方法

最后修改于 2025 年 4 月 8 日

本综合指南探讨 Python 的 __index__ 方法,这是一种用于索引操作中整数转换的特殊方法。我们将介绍基本用法、序列协议、自定义数字类型和实际示例。

基本定义

__index__ 方法是一种特殊方法,它返回对象的整数表示。当需要将对象转换为整数以进行索引操作时,会使用它。

主要特征:它必须返回一个整数,由 operator.index() 调用,并用于切片和索引操作。它提供无损整数转换,不同于 __int__

基本 __index__ 实现

这是一个简单的实现,展示了 __index__ 如何使对象能够用作列表或元组等序列中的索引。

basic_index.py
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

此示例展示了具有 __index__ 的对象如何直接用作列表索引。该方法返回存储的整数值,以满足索引的需要。

当对象在索引上下文中使用时,将隐式调用 __index__ 方法,将其转换为合适的整数索引。

使用 __index__ 进行切片

__index__ 也用于切片操作,允许将自定义对象用作切片索引。

slicing.py
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]

这演示了如何将具有 __index__ 的对象用于切片表示法。起始位置和停止位置都会自动转换为整数。

切片操作在执行切片之前,会对切片边界调用 __index__,从而在切片中启用自定义索引类型。

__index__ 和 __int__ 之间的区别

虽然相似,但 __index____int__ 的用途不同。 __index__ 专门用于无损整数转换。

index_vs_int.py
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__

这显示了这两种方法之间的不同行为。 __index__ 必须返回一个精确的整数,而 __int__ 可以执行转换。

在索引上下文中,首选 __index__,因为它保证了正确的整数值,而 __int__ 用于常规数字转换。

具有 __index__ 的自定义数字类型

__index__ 允许自定义数字类型与 Python 的索引系统集成,使其在序列中表现得像内置整数。

custom_number.py
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

当用作索引时,此二进制数字类将其值转换为整数。 __index__ 方法处理二进制到十进制的转换。

这种模式对于需要与 Python 的序列协议一起使用,同时保持其自身内部表示的自定义数字类型很有用。

将 __index__ 与 NumPy 数组一起使用

NumPy 数组和其他科学 Python 库使用 __index__ 进行数组索引,允许自定义索引类型与这些库一起使用。

numpy_index.py
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)

此示例显示了如何将自定义索引类型与 NumPy 数组一起使用。 __index__ 方法在数组访问之前转换索引值。

NumPy 在处理数组索引时调用 __index__,从而在保持数组访问性能的同时,启用自定义索引转换。

最佳实践

资料来源

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。 我从 2007 年开始撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程