在Python中,有没有一种简单的方法来判断某个东西是否不是序列?我试着这么做:if x is not sequence但是python不喜欢那样
- 相关:在python中,如何确定变量是否可Iterable?stackoverflow.com/questions/1952464/…
- 是的,但虽然所有序列都是iterables,但并非所有iterables都是序列(例如,集合和dict是内置的iterablecontainer,而不是序列)。
如果xTypeErroriter(x)将提高,但不能在线迭代检查的"接受",它"集和辞典,虽然其他非rejects"这样的None和序列号。
在其他的手,一弦(最想考虑的应用,而不是"单个项目"是在事实的序列(序列)的操作系统,任何测试,除非它是一specialcased字符串是要证实他们是)。简单的操作系统,这样的检查通常是不足够的。
在Python 2.6和更好的抽象基类,其强大的功能和原理,在其他系统的支持,他们提供更多的好,这样的"类检查"。
1 2 3 4 5 6 7 8 9 10 11 12 13
| >>> 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 |
你仍然是一个值得注意的字符串"序列"(因为他们),但至少你得到dicts和列出的方法。如果你想排除的字符串的概念"来自你的人,你可以使用collections.MutableSequence序列"(但这也excludes元组,这样序列,字符串是不可变的,但是是很明确的:),或
1 2 3 4 5 6
| import collections
def issequenceforme(obj):
if isinstance(obj, basestring):
return False
return isinstance(obj, collections.Sequence) |
对季节的味道,和它的热!-)
- 注意,对于实现序列协议但不涉及collections.Sequenceabc的对象,此代码示例将返回错误的结果。
- 是的:与简单的abc不同,sequence不实现__subclasshook__类方法,因此它永远不会自动识别一个选择不使用register的类(或从它继承的类),本质上不可能通过内省来判断类的__getitem__是否接受整数和片,是否引发IndexErroro。n错误的索引等——你只需要排除dict和set,本质上(如果你只是反省的话,那看起来确实"实现了序列协议"……但结果却不是这样!-)
- 集合很容易被排除,因为它们没有__getitem__,但是映射要困难得多。我所看到的最好的检查可能是寻找keys,就像dict.update一样,但这仍然需要很多东西。
- 所以要将我的自定义类型检测为序列,我必须对序列进行子类化?
- 上面提到的警告的一个很好的例子是numpy数组,它具有序列的所有必需属性,但不能被isinstance识别。如果这对麻木的数组甚至都不起作用,那么看起来就没有希望了。
- 在大多数实际情况下,不应将str视为序列,这就是hasattr(str,'__iter__')返回错误的原因。
- @Alexmartelli reversed需要一个序列。OrderedDict执行reversed,但isinstance(OrderedDict(), Sequence)是False。我不知道为什么。
我认为下面的代码片断:不是你想要的
1 2
| def is_sequence(obj):
return hasattr(type(obj), '__iter__') |
- 应该是hasattr(type(obj), '__iter__'),见此注释。
- 这是一个非常通用的变体,因为它与从特定类继承无关。它也适用于字典键序列。
- 字符串将通过此测试。hasattr(type("foo"), '__iter__')=>True。
由于Python的一个adheres"鸭打字的方法,是检查,如果有一些部件(面向对象方法)。
蛛网膜下腔出血蛛网膜下腔出血(SAH)的全长序列,序列和支持的项目,【DOC】切片。所以,这将是像这样:
1 2 3 4
| 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__()应该返回的项目数,如果返回一个项目(在__getitem__(i)TH序列,它是一项与映射,但不应该返回,__getitem__(slice(start, stop, step))subsequence),和__setitem__和__delitem__你期望的一样。这是这样一个合同,但是否真的对这些对象或不取决于是否或不是对象adheres合同。
请注意,该函数也将返回,在True映射是映射的,如从dict,也有这些方法。这对克服工作的比率,也就是比较丰满的,你可以:
1 2 3 4 5 6 7
| def is_sequence(obj):
try:
len(obj)
obj[0:0]
return True
except TypeError:
return False |
但大部分时间你不需要这个,你想要去的,如果对象是一个序列和捕获异常如果你愿意的话。这是更多的Python。
- 关于dict的重要一点是,如果你把它当作一个序列来处理,你只会得到键,而不是值,信息就会丢失。
- 如果使用hasattr(),则需要检查对象的类型,以获取魔法方法,而不是对象本身。请参阅python2和python3文档,了解如何查找特殊方法。
- @奥古拉谢谢你
- __setitem__和__delitem__只适用于可变序列(如非元组或字符串)。
2.6.5《Python文档介绍以下序列类型:字符串,字符串,列表,数组,缓冲区,和xrange。
1 2
| def isSequence(obj):
return type(obj) in [str, unicode, list, tuple, buffer, xrange] |
- 这个答案的问题在于它不会检测到不是内置类型的序列。python"sequence"是实现响应序列操作所需方法的任何对象。
- 另外,使用isinstance而不是type来支持子类。
在Python 2.6和3 +,你可以检查,如果它的collections.Sequence亚纲:
1 2 3
| >>> import collections
>>> isinstance(myObject, collections.Sequence)
True |
你必须使用Python中的collections.abc.Sequence(3.7 3.8 collections.Sequence将Python中的情况):
1 2 3
| >>> import collections.abc
>>> isinstance(myObject, collections.abc.Sequence)
True |
然而,这不会工作,实现__len__()鸭型序列和__getitem__()(但他们不应该collections.Sequence)的子类。但它会工作的所有Python内置序列类型:字符串,列表,元组,等。
在所有的序列学习是学习,不全是(例如,序列集和辞书为迭代变量,但不序列)。校验和是hasattr(type(obj), '__iter__')将返回True字典集。
你为什么这样做?在正常的方式是要求对某些类型的东西(或序列号或文件类对象等),然后使用它,在没有任何检测。在Python中,我们不使用语义信息来进行typically类的使用方法,简单的定义的(但这一个被称为"鸭打字")。我们也知道,我们是在选择原料药会怎么做;使用关键字参数,确定一个函数的preprocessing,或如果你想改变如何函数工作。
- 这是一个分配约束。如果我们传递的参数不是int、long或sequence,则需要引发TypeError。
- @尼古丁,认识到这项任务表明一个设计通常是非惯用和脆弱的。考虑正常情况,对象应该是一种类型的事物。如果一个参数应该是一个序列,但您得到一个int,那么当您对它进行索引或迭代时,您将已经得到一个TypeError。类似地,如果您尝试使用序列执行整数操作,您也会这样做。
- 提供一个一致的API(如果可能的话),它只需要一种类型的东西就可以让您编写更简单的代码,在出现问题时仍然会引发错误,但是它更强大,因为它支持您没有想到但满足真正目标的类型(例如,一些实现__len__和__getitem__的自定义类将Rk作为一个序列。)
- @Mikegraham提供了一个例子,在这个例子中,这样的东西可能是有用的,我正在尝试编写一个函数,它可以被赋予一个类型的单个对象,或者一个这样的对象的列表(或元组),我需要能够检测调用方是给了我一个序列,还是只给了一个对象。我知道这是否是一个好的设计是有争议的,但目前我想不出任何反对它的东西。
- @安特瑞德认为,目前最好的解决办法是让一个函数做一件事,而不是多件事。例如,总是需要一个序列。(您可以使用不同的API创建第二个函数。)问题是,没有好的方法来检测Python中的差异,而且很难理解执行多个操作而不是一个操作的函数。
- 有时候这是不可避免的。我正在处理的情况是,我正在处理JSON数据,其中一个特定的值可能是字符串、整数或整数列表。我不能更改JSON生成器,所以我必须在数据到达时处理它。
- @Mikegraham如果不进行检查,在某个时刻您确实会得到一个TypeError异常,但是这会使我无法正常地处理代码流。通过检查,我可以减轻这个问题,在这种无效的情况下,我可以更加控制该做什么。这实际上是关于是否使用异常作为错误处理机制的讨论。我一直反对它,也有多种现代语言不再支持例外(任何)。不幸的是,使用例外是Python式的方式,所以用惯用语来说你是(不幸的)对的。
为什么要问为什么
"如果要返回的长度。
1 2 3 4 5 6
| def haslength(seq):
try:
len(seq)
except:
return False
return True |