collections.abc为容器提供了一系列抽象基类
该模块提供了抽象基类,可以用来测试一个类是否提供了特定的接口;例如,它是可散列的还是映射的。
它们允许您检查某个对象是否具有类似于您正在检查的 ABC 的行为,而无需关心实际的实现。
例如,假设你有一个函数 F 根据参数的类型做某事,你可以直接检查是否是 list 或 tuple 或 dict 等的实例,然后做你的工作,但这限制你只有要使用这些,如果您然后创建自己的类具有类似的行为来说出列表,在某些情况下您关心并想将它与 F 一起使用,您发现它不起作用,那么您必须修改 F接受您的课程,但如果您检查 ABC,则不需要进行此类修改
现在是一个工作示例:假设您想要一个函数,该函数可以将列表中的所有元素都放在相同的位置,那么您可以这样做
def even_pos(data):
if isinstance(data,list):
return [data[i] for i in range(0,len(data),2)]
else:
raise ValueError("only a list")
并用作
>>> test = list(range(20))
>>> even_pos(test)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>>
没问题,但是你意识到元组与 this 函数关注的列表是一样的,你也可以将该检查添加到函数中,一切都很好,但是你的朋友告诉你他想使用你的功能,但他正在使用 acollections.deque
然后你的另一个朋友告诉...看到这里的模式了吗?我提到的所有对象(列表、元组、双端队列)都有相同的东西,并且可以通过该示例函数以相同的方式使用,并且所有这些行为都是在 ABC 中压缩的,所以isinstance(data,(list,tuple,collections.deque,...)
你只需要isinstance(data,abc.Sequence)
和该功能看起来像
from collections import abc
def even_pos(data):
if isinstance(data,abc.Sequence):
return [data[i] for i in range(0,len(data),2)]
else:
raise ValueError("only a Sequence")
>>> even_pos( list(range(10)) )
[0, 2, 4, 6, 8]
>>> even_pos( tuple(range(10)) )
[0, 2, 4, 6, 8]
>>> even_pos( range(10) ) # in python 3 range don't return a list, but a range object
[0, 2, 4, 6, 8]
>>> even_pos( "asdfghjh" )
['a', 'd', 'g', 'j']
>>>
现在您不需要知道正在使用的实际实现,只需知道它具有您想要的行为