首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >hasattr(obj,'__iter__')与集合

hasattr(obj,'__iter__')与集合
EN

Stack Overflow用户
提问于 2011-08-25 21:55:55
回答 5查看 4.6K关注 0票数 13

我见过一些帖子推荐isinstance(obj, collections.Sequence)而不是hasattr(obj, '__iter__')来确定某件事是否是一个列表。

)?

Python:检查一个对象是否是序列

起初,我很兴奋,因为测试一个对象是否有__iter__对我来说总是很脏的。但是,经过进一步的审查,这似乎仍然是最好的解决方案,因为isinstancecollection的测试没有一个产生相同的结果。collections.Sequence是关闭的,但它返回字符串的True

代码语言:javascript
复制
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

下面是我用来生成以下内容的代码:

代码语言:javascript
复制
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:编辑:编辑:--我只想检测内建类型:dictlist和--这是愚蠢的:)

编辑:--我应该包括让我研究这个问题的用例。我有一个函数,它接受一个arg,它可以是单个值,也可以是序列。所以我想检测它是什么,如果它是一个值的话,把它转换成一个序列,这样我就可以把它作为一个序列来处理。

代码语言:javascript
复制
if hasattr(arg, '__iter__'):
    arg= set(arg)
else:
    arg= set([arg])

解决这个问题的一种方法就是,如果不能迭代对象,就让它抛出异常。但这在我的用例中行不通。另一种解决方案是使用如下内容:

代码语言:javascript
复制
import collections

def issequenceforme(obj):
    if isinstance(obj, basestring):
        return False
    return isinstance(obj, collections.Sequence)

来自:Python:检查一个对象是否是序列

但是这需要定义这个函数,这使我不想使用它。

看来hasattr(arg, '__iter__')仍然是最好的选择。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-08-26 22:15:37

在与一些同事交谈后,我得出结论,hasattr(arg, '__iter__')可能是一个不错的班轮,但它远不是完美的,正如你们所指出的。这就是我最后的结局:

代码语言:javascript
复制
if isinstance(arg, basestring):
    arg= set([arg])
else:
    try:
        selection= set(arg)
    except TypeError:
        selection= set([arg])
票数 1
EN

Stack Overflow用户

发布于 2011-08-25 22:16:38

collections.Iterable将保证对象是可迭代的(比如使用for x in obj),但是检查__iter__不会。

字符串是可迭代的数据类型,但是在Python2.x上没有__iter__方法。

票数 5
EN

Stack Overflow用户

发布于 2011-08-25 21:58:20

您还可以将__iter__添加到您自己的类中,因此,任何低于hasattr(obj, '__iter__')的测试都不能保证检测到这些测试。您没有在问题中指定您只关心内置集合。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7197710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档