我可以检查 next()
方法,但这是否足够?有没有意识形态的方式?
最佳答案
在 Python 2.6 或更高版本中,用于此类行为检查的内置习惯用法是使用标准库的 collections
模块中的抽象基类进行的“成员资格检查”:
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
确实,这种检查是新抽象基类的主要设计原因(第二个重要的原因是在某些情况下提供“混合功能”,这就是为什么它们是 ABC 而不仅仅是接口(interface) - 但是不适用于 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)
是专门检查该条件的完全类似的方法。
关于python - 如何检查一个对象是否是 Python 中的迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3023503/