What does isinstance with a dictionary and abc.Mapping from collections doing?
我运行的代码是:
1 2 3 4 | >>> from collections import abc >>> mydict = {'test_key': 'test_value'} >>> isinstance(mydict, abc.Mapping) True |
我知道
似乎用
这不是更容易吗EDOCX1?5?
我做了一些搜索,在这个线程中找到了相关的注释:检查python变量类型的最佳(惯用)方法是什么?但是我还是很难弄清楚为什么在这里使用
collections.abc为容器提供一系列抽象基类
This module provides abstract base classes that can be used to test whether a class provides a particular interface; for example, whether it is hashable or whether it is a mapping.
它们允许您检查某个对象是否具有与您正在检查的ABC类似的行为,而不必关心实际的实现。
例如,假设您有一个函数f,它根据参数的类型来做一些事情,您可以直接检查它是否是list或tuple或dict或etc的实例,并完成您的工作,但是这限制了您只需要使用这些实例,如果您随后使自己的类具有类似的行为来说出list,在某些情况下,您会关心,并且wan不要将它与f一起使用,你会发现它不起作用,然后你必须修改f来接受你的类,但是如果你检查abc,这种修改是不必要的。
现在有一个工作示例:假设您想要一个函数,它从一个列表中给出所有元素的偶数位置,那么您可以这样做。
1 2 3 4 5 | 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") |
并用作
1 2 3 4 | >>> test = list(range(20)) >>> even_pos(test) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] >>> |
没问题,但是当你意识到一个元组和这个函数中的一个列表是一样的,你也可以把这个检查添加到函数中,一切都很好,但是你的朋友告诉你他想使用你的函数,但是他使用的是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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'] >>> |
现在,您不需要知道正在使用的实际实现,只需要知道它具有您想要的行为。
由于
对象不是dict实例的例子是多方面的,广泛应用于Web框架(例如aiohtp)。