【发布时间】:2011-11-04 02:12:09
【问题描述】:
我看到一些帖子推荐 isinstance(obj, collections.Sequence) 而不是 hasattr(obj, '__iter__') 来确定某个东西是否是一个列表。
len(object) or hasattr(object, __iter__)?
Python: check if an object is a sequence
起初我很兴奋,因为测试一个对象是否有__iter__ 对我来说总是很脏。但经过进一步审查后,这似乎仍然是最好的解决方案,因为在collection 上的isinstance 测试都没有产生相同的结果。 collections.Sequence 很接近,但它为字符串返回 True。
hasattr(obj, '__iter__')
set([]): True
{}: True
[]: True
'str': False
1: False
isinstance(obj, collections.Iterable)
set([]): True
{}: True
[]: True
'str': True
1: False
isinstance(obj, collections.Iterator)
set([]): False
{}: False
[]: False
'str': False
1: False
isinstance(obj, collections.Sequence)
set([]): False
{}: False
[]: True
'str': True
1: False
这是我用来生成这个的代码:
import collections
testObjs = [
set(),
dict(),
list(),
'str',
1
]
print "hasattr(obj, '__iter__')"
for obj in testObjs:
print ' %r: %r' % (obj, hasattr(obj, '__iter__'))
print
print "isinstance(obj, collections.Iterable)"
for obj in testObjs:
print ' %r: %r' % (obj, isinstance(obj, collections.Iterable))
print
print "isinstance(obj, collections.Iterator)"
for obj in testObjs:
print ' %r: %r' % (obj, isinstance(obj, collections.Iterator))
print
print "isinstance(obj, collections.Sequence)"
for obj in testObjs:
print ' %r: %r' % (obj, isinstance(obj, collections.Sequence))
print
我是否遗漏了什么或者hasattr(obj, '__iter__') 仍然是测试某些东西是否可迭代的最佳选择?
编辑:我只对检测内置类型感兴趣:dict、list 和 set。(编辑:这是愚蠢的 :) )
编辑:我应该包括让我研究这个的用例。我有一个函数,它接受一个可以是单个值或序列的 arg。所以我想检测它是什么,如果它是一个单一的值,就把它变成一个序列,这样我就可以把它当作一个序列来处理。
if hasattr(arg, '__iter__'):
arg= set(arg)
else:
arg= set([arg])
对此的一种解决方案是,如果对象无法迭代,则让它抛出异常。但这在我的用例中不起作用。另一种解决方案是使用类似的东西:
import collections
def issequenceforme(obj):
if isinstance(obj, basestring):
return False
return isinstance(obj, collections.Sequence)
发件人: Python: check if an object is a sequence
但这需要定义这个函数,这让我不想使用它。
看起来hasattr(arg, '__iter__') 仍然是最好的选择。
【问题讨论】:
-
就个人而言,我检查
isinstance( obj, basestring )(可迭代但通常不是您想要迭代的东西),如果不是,则对其进行迭代,捕获异常。
标签: python collections iterator