在Python 2.6或更高版本中,用于此类行为检查的内置习惯用法是“成员资格检查”,其中collections
包含标准库模块中的抽象基类:@H_403_3@
>>> 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__
在这种情况下),因此您不必这样做。@H_403_3@
如果您仍旧使用Python的较旧版本,则“请求宽恕比允许许可更好”:@H_403_3@
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
请注意,对于这种特殊情况,您通常会希望对字符串进行特殊处理(可迭代,但是大多数应用程序上下文无论如何都希望将其视为“标量”)。无论您使用哪种方法来检查可迭代性,如果您需要这种特殊的大小写,只需在其前面添加一个检查即可isinstance(x, basestring)
,例如:@H_403_3@
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
上,而不是它是否可迭代***(所有迭代器都是可迭代的,但反之则不行- 并非所有的迭代器都是迭代器)。 isinstance(x, collections.Iterator)
是专门检查该状况的完全相似的方法。@H_403_3@