Python hasattr(obj和iter)与集合
我看到一些帖子建议使用Python hasattr(obj和iter)与集合,python,collections,iterator,Python,Collections,Iterator,我看到一些帖子建议使用isinstance(obj,collections.Sequence)而不是hasattr(obj,'.''.'iter'.'来确定某个东西是否是一个列表 起初我很兴奋,因为测试一个对象是否有\uuuu iter\uuuu对我来说总是很肮脏。但在进一步审查之后,这似乎仍然是最好的解决方案,因为对集合进行的isinstance测试都不会产生相同的结果collections.Sequence已关闭,但它返回字符串的True hasattr(obj, '__iter__')
isinstance(obj,collections.Sequence)
而不是hasattr(obj,'.''.'iter'.'
来确定某个东西是否是一个列表
起初我很兴奋,因为测试一个对象是否有\uuuu iter\uuuu
对我来说总是很肮脏。但在进一步审查之后,这似乎仍然是最好的解决方案,因为对集合进行的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'.'uuu')
仍然是测试某些东西是否合适的最佳选择
编辑:我只对检测内置类型感兴趣: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,'.'uu iter'.'uu')
仍然是最好的选择。您也可以将\uuu iter'.
添加到您自己的类中,因此任何缺少hasattr(obj,'.'uu iter'.
的测试都不能保证检测到它们。您没有在问题中指定您只关心内置集合。集合。可伸缩性将保证对象是否可伸缩(如在obj
中为x使用),但选中则不会
字符串是一种可移植的数据类型,但在Python2.x上它没有\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu方法。在与一些同事交谈后,我得出结论,hasattr(arg,“\uuuuuuuuuuuuuuuuuuuiter_uuuuuuuu')
可能是一个不错的单行程序,但正如你们所指出的那样,它。这就是我的结局:
if isinstance(arg, basestring):
arg= set([arg])
else:
try:
selection= set(arg)
except TypeError:
selection= set([arg])
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
collections.Iterable
用于一个Iterable对象,即某种形式的容器,允许您逐个迭代它包含的对象。字符串包括在其中,因为您可以迭代每个字符都是字符串
collections.Sequence
用于保证迭代顺序的iterable对象子集。列表和字符串将返回True
,因为同一列表或字符串的迭代顺序始终相同,而集合和字典将返回False
,因为您不知道内部对象的顺序
如果您确定只想检测内置类型(通常被认为是可疑行为,首选),那么您可以这样做:
if isinstance(arg, (set, list, dict, tuple)):
print "I got a built-in iterable."
else:
print "Hey, this ain't iterable!"
然而,您提出的解决方案更好——处理任何特殊情况(例如,您的情况下的字符串),然后使用duck类型。这样,其他人就可以使用任何适合他们需要的容器,并负责确保它符合您的代码要求
问题:我看到一些帖子建议使用isinstance(obj,collections.Sequence)而不是hasattr(obj,'.''.'iter'.'来确定某个东西是否是一个列表
要确定某物是否是,最可靠的方法是尝试创建一个。这将确定对象是否实际可编辑:
def is_iterable(obj):
try:
iter(obj)
except TypeError:
return False
else:
return True
isinstance(obj, collections.Iterable)
一种稍微不太可靠,但外观整洁的方法是针对测试对象进行测试。这将测试对象是否具有_uiter _;()方法,或者是否注册为Iterable(例如,str的实例没有_uiter _;()方法,但注册为Iterable):
如果您对列表和类似列表的对象特别感兴趣,可以针对可变序列ABC进行测试:
也就是说,如果您依赖的对象具有特定的类似列表的行为,python的方法是假设该方法存在,如果不存在,则捕获异常。这被称为。就个人而言,我检查isinstance(obj,basestring)
(iterable,但通常不是你想要迭代的东西),如果不是,就迭代它,捕捉异常。我只对检测内置类型感兴趣,比如dict
,list
,和set
。我将把这一点添加到我的问题中。检查基本字符串
是常见且有用的。另一个有用的检查是集合.Mapping
(而不是dict
),特别是因为您似乎对集合感兴趣,Mapping
的键始终是集合。