lst = [10, 20, 30]
print(lst[1]) # 输出 20
这背后其实是调用了:
lst.__getitem__(1)
lst[1]
→ lst.__getitem__(1)
只是 Python 层的入口,真正的“取值”动作在 C 里完成
你也可以自己写一个类,只要实现了 __getitem__
,就能像序列一样用索引取值:
class MySeq:
def __getitem__(self, index):
return f"你访问了索引 {index}"
obj = MySeq()
print(obj[10]) # 输出:你访问了索引 10
lst[1]
只是语法糖,底层就是调用 lst.__getitem__(1)
lst.__getitem__(1)
只是 Python 层的入口,真正的“取值”动作在 C 里完成
序列里面是由__getitem__方法就可以,为什么我们自己写一个类,只要实现了 __getitem__,也可以就能像序列一样用索引取值?这是什么原理
解释器根本不关心你是不是“官方序列”,只要你在自己的类里实现了 __getitem__
,它就按统一协议把 obj[key]
翻译成 type(obj).__getitem__(obj, key)
. 语法糖层面:统一转成一次 C 级调用
obj[key]
在字节码里就是 BINARY_SUBSCR
。obj
是 list、tuple 还是你自定义的类,都走同一条路__getitem__
,它就“像序列一样”可用索引取值,这就是 Python 的鸭子类型(duck typing)。