有没有像isiterable这样的方法?到目前为止,我找到的唯一解决办法就是打电话
hasattr(myObj, '__iter__')
但我不确定这是否万无一失。
有没有像isiterable这样的方法?到目前为止,我找到的唯一解决办法就是打电话
hasattr(myObj, '__iter__')
但我不确定这是否万无一失。
当前回答
你可以试试这个:
def iterable(a):
try:
(x for x in a)
return True
except TypeError:
return False
如果我们可以创建一个迭代它的生成器(但从不使用生成器,以免占用空间),那么它就是可迭代的。听起来像是"废话"一类的事。为什么首先需要确定一个变量是否可迭代?
其他回答
在我的脚本中,我经常发现定义一个可迭代函数很方便。 (现在合并了Alfe建议的简化):
import collections
def iterable(obj):
return isinstance(obj, collections.Iterable):
因此,您可以测试任何对象是否具有非常可读的可迭代形式
if iterable(obj):
# act on iterable
else:
# not iterable
就像你对可调用函数所做的那样
编辑:如果你安装了numpy,你可以简单地做: 简单地说是什么
def iterable(obj):
try: iter(obj)
except: return False
return True
如果没有numpy,可以简单地实现这段代码或上面的代码。
在Python <= 2.5中,你不能也不应该——iterable是一个“非正式的”接口。
但是从Python 2.6和3.0开始,你可以利用新的ABC(抽象基类)基础设施以及一些内置的ABC,这些ABC在collections模块中可用:
from collections import Iterable
class MyObject(object):
pass
mo = MyObject()
print isinstance(mo, Iterable)
Iterable.register(MyObject)
print isinstance(mo, Iterable)
print isinstance("abc", Iterable)
现在,这是否可取,或者是否有效,只是一个惯例的问题。正如你所看到的,你可以将一个不可迭代的对象注册为Iterable——它将在运行时引发一个异常。因此,isinstance获得了一个“新的”含义——它只是检查“声明的”类型兼容性,这在Python中是一个很好的方法。
另一方面,如果你的对象不能满足你所需要的接口,你会怎么做?举个例子:
from collections import Iterable
from traceback import print_exc
def check_and_raise(x):
if not isinstance(x, Iterable):
raise TypeError, "%s is not iterable" % x
else:
for i in x:
print i
def just_iter(x):
for i in x:
print i
class NotIterable(object):
pass
if __name__ == "__main__":
try:
check_and_raise(5)
except:
print_exc()
print
try:
just_iter(5)
except:
print_exc()
print
try:
Iterable.register(NotIterable)
ni = NotIterable()
check_and_raise(ni)
except:
print_exc()
print
如果对象不满足您的期望,则抛出TypeError,但如果已经注册了正确的ABC,则检查将毫无用处。相反,如果__iter__方法可用,Python将自动识别该类的object为Iterable。
如果你只是期望一个可迭代对象,遍历它,然后忘记它。另一方面,如果您需要根据输入类型执行不同的操作,那么您可能会发现ABC基础结构非常有用。
不是真的“正确”,但可以作为最常见的类型,如字符串,元组,浮动等快速检查…
>>> '__iter__' in dir('sds')
True
>>> '__iter__' in dir(56)
False
>>> '__iter__' in dir([5,6,9,8])
True
>>> '__iter__' in dir({'jh':'ff'})
True
>>> '__iter__' in dir({'jh'})
True
>>> '__iter__' in dir(56.9865)
False
有很多方法来检查一个对象是否可迭代:
from collections.abc import Iterable
myobject = 'Roster'
if isinstance(myobject , Iterable):
print(f"{myobject } is iterable")
else:
print(f"strong text{myobject } is not iterable")
在我的代码中,我用来检查非可迭代对象:
hasattr (myobject, __trunc__’)
这非常快,也可以用来检查可迭代对象(使用not)。
我不是100%确定这个解决方案是否适用于所有对象,也许其他可以提供一些更多的背景。__trunc__方法与数值类型相关(所有可以舍入为整数的对象都需要它)。但是我没有发现任何包含__trunc__和__iter__或__getitem__的对象。