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