testing一个variables是一个列表还是元组

在python中,testingvariables是否包含列表或元组的最佳方法是什么? (即集合)

就像这里所说的那样是邪恶的吗? http://www.canonical.org/~kragen/isinstance/

更新:我想区分一个string列表最常见的原因是当我有一个无限深的嵌套树/数据结构的列表的列表的列表的string等,我正在探索与recursionalgorithm,我需要知道我什么时候击中“叶子”节点。

继续,如果你需要的话使用isinstance 。 这有点邪恶,因为它排除了自定义序列,迭代器和其他你可能真正需要的东西。 但是,有时候,如果某个人传递了string,则需要采取不同的行为。 我的首选项将是明确检查为strunicode像这样:

 import types isinstance(var, types.StringTypes) 

注意不要把types.StringType types.StringTypes 。 后者包含strunicode对象。

types模块被许多人认为是过时的,只是直接检查对象的types,所以如果你不想使用上面的代码,你可以select显式地检查strunicode ,如下所示:

 isinstance(var, (str, unicode)): 

编辑:

更好的是:

 isinstance(var, basestring) 

结束编辑

在其中的任何一个之后,你可以退后一步,就像你正在获得一个正常的序列一样,让非序列产生适当的例外。

看到关于types检查的“邪恶”的事情并不是说你可能希望针对某种types的对象采取不同的行为,那就是人为地限制你的函数做正确的事情,而这种事情对象types会做正确的事情。 如果您有一个未经过types检查的最终回退,则删除此限制。 应该注意的是,太多的types检查是代码异味,表明你可能想要做一些重构,但这并不意味着你应该从getgo中避免它。

 if type(x) is list: print 'a list' elif type(x) is tuple: print 'a tuple' else: print 'neither a tuple or a list' 

使用isinstance没有任何问题,只要它不是多余的。 如果一个variables应该只是一个列表/元组,然后logging接口,只是使用它。 否则,支票是完全合理的:

 if isinstance(a, collections.Iterable): # use as a container else: # not a container! 

这种types的检查确实有一些很好的用例,例如标准的stringstartswith / endswith方法(尽pipe准确的说,这些在CPython中用C语言实现,使用明确的检查来查看它是否是一个元组 – 有多种方法解决这个问题,正如你在文章中提到的那样)。

明确的检查通常比尝试将对象用作容器和处理exception要好 – 这可能会导致代码部分或不必要地运行的各种问题。

将参数logging为需要成为序列,并将其用作序列。 不要检查types。

如何: hasattr(a, "__iter__")

它告诉是否返回的对象可以作为生成器迭代。 默认情况下,元组和列表可以,但不能是stringtypes。

Python使用“鸭子打字”,即如果一个variableskawaks像一只鸭子,它一定是一只鸭子。 在你的情况下,你可能希望它是可迭代的,或者你想访问某个索引的项目。 你应该这样做:即在try块中for var:var[idx]的对象,如果发生exception,则不是鸭子…

 >>> l = [] >>> l.__class__.__name__ in ('list', 'tuple') True 

在Python 2.8 type(list) is list返回false
我会build议比较types在这个可怕的方式:

 if type(a) == type([]) : print "variable a is a list" 

(至less在我的系统上,在Mac OS X Yosemite上使用anaconda)

如果您只需要知道是否可以将foo[123]表示法与variables一起使用,则可以使用hasattr(foo, '__getitem__') )检查是否存在__getitem__属性(这是python在通过索引访问时调用的) hasattr(foo, '__getitem__')

原则上,我同意上面的Ignacio,但也可以使用type来检查是否是元组或列表。

 >>> a = (1,) >>> type(a) (type 'tuple') >>> a = [1] >>> type(a) (type 'list') 

如果你真的想要处理任何东西作为函数参数,必须更复杂的testing。

 type(a) != type('') and hasattr(a, "__iter__") 

虽然通常只要说明一个函数需要迭代,然后只检查type(a) != type('')就足够了。

也可能发生这样的情况,对于一个string,你有一个简单的处理path,或者你会很好,做一个拆分等,所以你不想大声嚷嚷,如果有人给你一些奇怪的东西,让他有一个例外。