如何检查对象是否是Python中的迭代器? [英] How can I check if an object is an iterator in Python?

查看:106
本文介绍了如何检查对象是否是Python中的迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以查看 next()方法,但这还够吗?有没有一种思想方式?

I can check for a next() method, but is that enough? Is there an ideomatic way?

推荐答案

在Python 2.6或更高版本中,这种行为检查的设计用语是会员资格检查使用标准库的集合模块中的抽象基类:

In Python 2.6 or better, the designed-in idiom for such behavioral checks is a "membership check" with the abstract base class in the collections module of the standard library:

>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True

的确,这种检查是新抽象基类的主要设计原因(第二个重要的是在某些情况下提供mixin功能,这就是为什么它们是ABC而不仅仅是接口 - 但这不适用于 collections.Iterable ,它存在严格以允许使用 isinstance issubclass )。 ABCs允许实际上不从它们继承的类被注册为子类,因此这些类可以是ABC的子类,用于这种检查;并且,他们可以在内部对特殊方法执行所有必需的检查(在这种情况下 __ iter __ ),所以你没必要。

Indeed, this kind of checks is the prime design reason for the new abstract base classes (a second important one is to provide "mixin functionality" in some cases, which is why they're ABCs rather than just interfaces -- but that doesn't apply to collections.Iterable, it exists strictly to allow such checks with isinstance or issubclass). ABCs allow classes that don't actually inherit from them to be "registered" as subclasses anyway, so that such classes can be "subclasses" of the ABC for such checks; and, they can internally perform all needed checks for special methods (__iter__ in this case), so you don't have to.

如果你坚持使用旧版本的Python,最好是请求宽恕而非许可:

If you're stuck with older releases of Python, "it's better to ask forgiveness than permission":

def isiterable(x):
  try: iter(x)
  except TypeError: return False
  else: return True

但这并不像新方法那么快速和简洁。

but that's not as fast and concise as the new approach.

请注意,对于这种特殊情况,您经常需要特殊情况字符串(可迭代但大多数应用程序上下文无论如何都要视为标量)。无论你使用什么方法来检查可迭代性,如果你需要这样的特殊套管,只需要检查 isinstance(x,basestring) - 例如:

Note that for this special case you'll often want to special-case strings (which are iterable but most application contexts want to treat as "scalars" anyway). Whatever approach you're using to check iterableness, if you need such special casing just prepend a check for isinstance(x, basestring) -- for example:

def reallyiterable(x):
  return not isinstance(x, basestring) and isinstance(x, collections.Iterable)

编辑:正如评论中所指出的,问题集中在一个对象是否是一个iter *** ator ***而不是它是否真的*** ***(所有迭代器都是可迭代的,但反之亦然 - 并非所有迭代都是迭代器)。 isinstance(x,collections.Iterator)是专门检查该条件的完全类似方式。

Edit: as pointed out in a comment, the question focuses on whether an object is an iter***ator*** rather than whether it's iter***able*** (all iterators are iterable, but not vice versa -- not all iterables are iterators). isinstance(x, collections.Iterator) is the perfectly analogous way to check for that condition specifically.

这篇关于如何检查对象是否是Python中的迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆