Ale*_*lli 56
在Python 2.6或更高版本中,这种行为检查的设计用语是collections
标准库模块中抽象基类的"成员资格检查" :
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
Run Code Online (Sandbox Code Playgroud)
实际上,这种检查是新抽象基类的主要设计原因(第二个重要的是在某些情况下提供"mixin功能",这就是为什么它们是ABCs而不仅仅是接口 - 但这并不是'适用于collections.Iterable
,它严格存在以允许与isinstance
or issubclass
)进行此类检查.ABCs允许实际上不从它们继承的类被"注册"为子类,因此这些类可以是ABC的"子类"以进行此类检查; 并且,他们可以在内部执行特殊方法所需的所有检查(__iter__
在这种情况下),因此您不必这样做.
如果你坚持使用旧版本的Python,"请求宽恕而不是许可":
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
Run Code Online (Sandbox Code Playgroud)
但这并不像新方法那么快速和简洁.
请注意,对于这种特殊情况,您通常需要特殊情况字符串(可迭代,但大多数应用程序上下文仍然希望将其视为"标量").无论您使用什么方法来检查可迭代性,如果您需要这样的特殊套管,只需要预先检查isinstance(x, basestring)
- 例如:
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
Run Code Online (Sandbox Code Playgroud)
编辑:正如评论中指出的那样,问题集中在一个对象是否是一个对象***而不是它是否为*********(所有迭代器都是可迭代的,但反之亦然 -并非所有迭代都是迭代器). isinstance(x, collections.Iterator)
是特别检查这种情况的完全类似的方法.
sys*_*out 16
如果对象实现迭代器协议,则该对象是可迭代的.
您可以__iter__()
使用以下方法检查方法的存在:
hasattr(object,'__iter__')
Run Code Online (Sandbox Code Playgroud)
在Python 2.x中,这种方法错过了str对象和其他内置序列类型,如unicode,xrange,buffer.它适用于Python 3.
另一种方法是使用iter方法测试它:
try:
iter(object)
except TypeError:
#not iterable
Run Code Online (Sandbox Code Playgroud)
有一个比其他答案建议的更好的方法。
在 Python 中,我们有两种东西:Iterable
和Iterator
。一个物体就是Iterable
它能给你的Iterator
。iter()
当你使用它时它会这样做。一个对象就是Iterator
您可以用来next()
顺序浏览其元素的对象。例如,map()
返回Iterator
和list
is Iterable
。
以下是更多详细信息。
下面的代码说明了如何检查这些类型:
from collections.abc import Iterable, Iterator
r = [1, 2, 3]
e = map(lambda x:x, r)
print(isinstance(r, Iterator)) # False, because can't apply next
print(isinstance(e, Iterator)) # True
print(isinstance(r, Iterable)) # True, because can apply iter()
print(isinstance(e, Iterable)) # True, note iter() returns self
Run Code Online (Sandbox Code Playgroud)
要成为迭代器,对象必须通过三个测试:
obj
有一个__iter__
方法obj
有一个next
方法(或__next__
在Python 3中)obj.__iter__()
回报 obj
所以,你自己的测试看起来像:
def is_iterator(obj):
if (
hasattr(obj, '__iter__') and
hasattr(obj, 'next') and # or __next__ in Python 3
callable(obj.__iter__) and
obj.__iter__() is obj
):
return True
else:
return False
Run Code Online (Sandbox Code Playgroud)
小智 6
from collections.abc import Iterator
isinstance(object, Iterator)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12302 次 |
最近记录: |