Python有很多神奇的方法,其中大部分都是某些协议的一部分。我熟悉“迭代器协议”和“数字协议”,但最近偶然发现了术语"sequence protocol"。但即使经过一些研究,我也不确定“序列协议”是什么。什么是Python的序列协议?
例如,C API函数PySequence_Check
检查(根据文档)某些对象是否实现“序列协议”。该source code表明这是一类,这不是一个字典,但实现__getitem__
方法是大致相同什么上iter
文件还指出:
[...]必须支持序列协议(该
__getitem__()
方法用从0开始的整数参数)。[...]
但下手0
要求不是那种在PySequence_Check
“落实”。
然后里面还有collections.abc.Sequence
类型,它基本上是说实例必须实现__reversed__
,__contains__
,__iter__
和__len__
。
但是通过该定义,实施“序列协议”的类不一定是序列,例如"data model"和抽象类garantuee,序列具有长度。但是使用len(an_instance_of_that_class)
时,仅执行__getitem__
(传递PySequence_Check
)的类会引发异常。
有人能请我澄清序列和序列协议(如果除了阅读源代码之外还有协议的定义)和何时使用哪种定义之间的区别?
'collections.abc.Sequence'需要'__getitem__'和'__len__'。其他的一切都有mixin方法。关于迭代,如果只是'__getitem__'被定义为没有'__iter__',那么内建的'iter'实例化一个简单的迭代器,它从索引0开始。对于'revers'来工作'__len__'也必须被定义,所以它可以从最后一个索引开始。 – eryksun
@eryksun但是一个类不需要'__len__'来实现序列协议(就“PySequence_Check”而言)。并且实现'__len__'和'__getitem__'但不从'collections.abc.Sequence'继承的类没有通过'isinstance(an_instance,Sequence)'。这就是触发我的问题的原因。 :) – MSeifert