我看过几个帖子推荐 isinstance(obj, collections.Sequence)
代替 hasattr(obj, '__iter__')
确定某事是否是一个清单。
len(object)或hasattr(object,__iter__)?
起初我很兴奋,因为测试对象是否有 __iter__
对我来说总是很脏。但经过进一步的审查,这似乎仍然是最好的解决方案,因为没有 isinstance
测试 collection
产生相同的结果。 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)
但是这需要定义这个功能,这使我不想使用它。
看起来像 hasattr(arg, '__iter__')
仍然是最好的选择。