我见过一些帖子推荐isinstance(obj, collections.Sequence)而不是hasattr(obj, '__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__')仍然是测试可迭代性的最佳选择?
set.(EDIT:编辑:编辑:--我只想检测内建类型:dict、list和--这是愚蠢的:)
编辑:--我应该包括让我研究这个问题的用例。我有一个函数,它接受一个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__')仍然是最好的选择。
发布于 2011-08-26 22:15:37
在与一些同事交谈后,我得出结论,hasattr(arg, '__iter__')可能是一个不错的班轮,但它远不是完美的,正如你们所指出的。这就是我最后的结局:
if isinstance(arg, basestring):
arg= set([arg])
else:
try:
selection= set(arg)
except TypeError:
selection= set([arg])发布于 2011-08-25 22:16:38
collections.Iterable将保证对象是可迭代的(比如使用for x in obj),但是检查__iter__不会。
字符串是可迭代的数据类型,但是在Python2.x上没有__iter__方法。
发布于 2011-08-25 21:58:20
您还可以将__iter__添加到您自己的类中,因此,任何低于hasattr(obj, '__iter__')的测试都不能保证检测到这些测试。您没有在问题中指定您只关心内置集合。
https://stackoverflow.com/questions/7197710
复制相似问题