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

在python中有一个简单的方法来判断一个事物是不是一个序列? 我试图做: if x is not sequence但python不喜欢那样

如果x不能被迭代, iter(x)会引发一个TypeError – 但是它检查“接受”集和字典,尽pipe它会“拒绝”其他非序列,比如None和数字。

另一方面,string(大多数应用程序想要考虑“单个项目”而不是序列)实际上是序列的(因此,除非string专用,否则任何testing都将确认它们)。 所以,这样简单的检查通常是不够的。

在Python 2.6及更高版本中,引入了抽象基类 ,除了其他强大的function之外,它们还为这种“类别检查”提供了更好的系统支持。

 >>> import collections >>> isinstance([], collections.Sequence) True >>> isinstance((), collections.Sequence) True >>> isinstance(23, collections.Sequence) False >>> isinstance('foo', collections.Sequence) True >>> isinstance({}, collections.Sequence) False >>> isinstance(set(), collections.Sequence) False 

你会注意到string仍然被认为是“一个序列”(因为它们 ),但是至less你得到了一些string并且排除了障碍。 如果你想从“正在序列”的概念中排除string,你可以使用collections.MutableSequence (但也不包括元组,像string一样,是序列,但是不可变),或者明确地做:

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

季节去品尝,并服务热! – )

Python 2.6.5文档描述了以下序列types:string,Unicodestring,列表,元组,缓冲区和xrange。

 def isSequence(obj): return type(obj) in [str, unicode, list, tuple, buffer, xrange] 

你为什么做这个? 这里的正常方法是要求某种types的东西(序列或数字或类似文件的对象等),然后在不检查任何东西的情况下使用它。 在Python中,我们通常不使用类来传递语义信息,而是简单地使用定义的方法(这被称为“鸭子types”)。 我们也更喜欢API,我们确切地知道期望什么; 使用关键字参数,预处理或定义另一个函数,如果你想改变一个函数的工作方式。

由于Python“坚持”鸭子打字,其中一种方法是检查一个对象是否有某个成员(方法)。

一个序列有长度,有序列的项目,支持切片[ doc ]。 所以,这将是这样的:

 def is_sequence(obj): t = type(obj) return hasattr(t, '__len__') and hasattr(t, '__getitem__') # additionally: and hasattr(t, '__setitem__') and hasattr(t, '__delitem__') 

它们都是特殊的方法, __len__()应该返回项目的数量, __len__() __getitem__(i)应该返回一个项目(顺序是第i个项目, 没有映射), __getitem__(slice(start, stop, step))应该返回子序列, __setitem____delitem__就像你期望的那样。 这是这样一个合同,但是这个对象是否真的这样做取决于这个对象是否遵守合同。

请注意 ,上面的函数也会返回True进行映射,例如dict ,因为映射也有这些方法。 为了克服这个问题,你可以做更重的工作:

 def is_sequence(obj): try: len(obj) obj[0:0] return True except TypeError: return False 

大多数情况下,你不需要这个,只要做你想要的东西,就好像对象是一个序列,并且如果你愿意的话可以捕获一个exception。 这是比较pythonic。

我认为下面的代码片断是你想要的:

 def is_sequence(obj): return hasattr(type(obj), '__iter__') 

为什么问为什么

尝试得到一个长度,如果exception返回false

 def haslength(seq): try: len(seq) except: return False return True