testing一个variables是一个列表还是元组
在python中,testingvariables是否包含列表或元组的最佳方法是什么? (即集合)
就像这里所说的那样是邪恶的吗? http://www.canonical.org/~kragen/isinstance/
更新:我想区分一个string列表最常见的原因是当我有一个无限深的嵌套树/数据结构的列表的列表的列表的string等,我正在探索与recursionalgorithm,我需要知道我什么时候击中“叶子”节点。
继续,如果你需要的话使用isinstance
。 这有点邪恶,因为它排除了自定义序列,迭代器和其他你可能真正需要的东西。 但是,有时候,如果某个人传递了string,则需要采取不同的行为。 我的首选项将是明确检查为str
或unicode
像这样:
import types isinstance(var, types.StringTypes)
注意不要把types.StringType
types.StringTypes
。 后者包含str
和unicode
对象。
types
模块被许多人认为是过时的,只是直接检查对象的types,所以如果你不想使用上面的代码,你可以select显式地检查str
和unicode
,如下所示:
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,或者你会很好,做一个拆分等,所以你不想大声嚷嚷,如果有人给你一些奇怪的东西,让他有一个例外。