在Python 2.6或更高版本中,用于此类行为检查的内置习惯用法是“成员资格检查”,其中
collections包含标准库模块中的抽象基类:
>>> import collections>>> isinstance('ciao', collections.Iterable)True>>> isinstance(23, collections.Iterable)False>>> isinstance(xrange(23), collections.Iterable)True的确,这种检查是新抽象基类设计的主要原因(第二个重要的问题是在某些情况下提供“ mixin功能”,这就是为什么它们是ABC而不是接口的原因-但这不是)
t适用于
collections.Iterable, 严格
存在允许使用
isinstance或进行此类检查的情况
issubclass。ABC允许实际上没有从其继承的类被“注册”为子类,因此此类类可以成为ABC的“子类”进行此类检查;并且,他们可以在内部执行特殊方法的所有必要检查(
__iter__在这种情况下),因此您不必这样做。
如果您仍旧使用Python的较旧版本,则“请求宽恕比允许许可更好”:
def isiterable(x): try: iter(x) except TypeError: return False else: return True
但这并不像新方法那样简洁明了。
请注意,对于这种特殊情况,您通常会希望对字符串进行特殊处理(可迭代,但是大多数应用程序上下文无论如何都希望将其视为“标量”)。无论您使用哪种方法来检查可迭代性,如果您需要这种特殊的大小写,只需在其前面添加一个检查即可
isinstance(x,basestring),例如:
def reallyiterable(x): return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
编辑* :正如评论中指出的那样,问题集中在一个对象是否是迭代器上,而不是它是否可迭代***(所有迭代器都是可迭代的,但反之则不行-
并非所有的迭代器都是迭代器)。
isinstance(x, collections.Iterator)是专门检查该状况的完全相似的方法。



