6

我正在寻找一种方法来测试一个对象是否不是“list-ish”类型,即 - 不仅该对象不可迭代(例如 - 您还可以在字符串上运行iter,或者在一个简单的实现iter的对象)但该对象不在列表族中。我将“ list ”系列定义为 list/tuple/set/frozenset,或者任何从它们继承的东西,但是 - 因为可能有一些我遗漏的东西,我想找到一种比运行isinstance所有的更通用的方法那些类型。

我想到了两种可能的方法,但似乎都有些尴尬,因为它们对每种可能的列表类型进行了非常多的测试,我正在寻找更通用的解决方案。

第一个选项:

return not isinstance( value, (frozenset, list, set, tuple,) )

第二种选择:

return not hasattr(value, '__iter__')

测试__iter__属性是否足够?有没有更好的方法来查找对象是否不是列表类型?

提前致谢。

编辑

引用@Rosh Oxymoron 的解决方案的评论):
现在更好地考虑定义,我相信说我需要找到定义中不是数组类型的所有内容,但它仍然可以是字符串/其他简单对象...
检查collections.Iterable仍然会给我实现该方法的对象的True 。__iter__

4

2 回答 2

6

没有术语“list-ish”,也没有内置魔法check_if_value_is_an_instance_of_some_i_dont_know_what_set_of_types

你的解决方案not isinstance( value, (frozenset, list, set, tuple,) )非常好 - 它清晰明确。

于 2011-08-28T14:11:12.403 回答
3

没有这样的家庭——它没有明确的定义,自然没有办法检查它。最接近的可能是不是字符串的可迭代对象。您可以测试对象是否可迭代,然后显式检查它是否为字符串:

if isinstance(ob, collections.Iterable) and not isinstance(ob, types.StringTypes):
    print "An iterable container"

更好的方法是总是要求一个可迭代的对象,当你需要传递一个字符串S时,改为传递[S]。传递字符串的能力是一个特性,例如:

alphabet = set('abcdefgijklmopqrstuvwxyz')

如果您使用特殊情况的字符串,您将:

  1. 以最自然的方式传递字符集合,打破使用函数的能力。
  2. 为用户定义的字符串类型和/或其他类似字符串的容器创建不一致(例如array.array,可以表示一大块数据,就像字符串一样)。

字符串可用于表示单个文本和字符集合,并且由于第二个,它也是列表式的。

于 2011-08-28T14:17:03.027 回答