在python中,测试变量是否包含列表或元组的最佳方法是什么?(即。一组)

isinstance()是否如这里所建议的那样邪恶?http://www.canonical.org/~kragen/isinstance/

更新:我想要区分列表和字符串的最常见原因是,当我有一些无限深嵌套的字符串列表的列表的列表的树/数据结构时,我正在用递归算法探索,我需要知道什么时候我已经碰到了“叶”节点。


当前回答

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

其他回答

Python使用“鸭子类型”,即如果一个变量像鸭子一样叫,它一定是一只鸭子。在您的情况下,您可能希望它是可迭代的,或者您希望访问某个索引处的项。你应该这样做:即在try块中使用对象for var:或var[idx],如果你得到一个异常,它不是鸭子…

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

那么:hasattr(a, "__iter__")呢?

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

如果你需要,请使用isinstance。这有点邪恶,因为它排除了自定义序列、迭代器和其他您可能实际需要的东西。然而,有时如果有人传递一个字符串,则需要采取不同的行为。我的偏好是显式检查str或unicode,就像这样:

import types
isinstance(var, types.StringTypes)

注意:不要搞错类型。StringType用于types.StringTypes。后者包含str和unicode对象。

types模块被很多人认为是过时的,更倾向于直接检查对象的类型,所以如果你不想使用上面的方法,你可以选择显式检查str和unicode,就像这样:

isinstance(var, (str, unicode)):

编辑:

更好的是:

isinstance(var, basestring)

最后编辑

在完成这两种操作后,您可以退回到获取正常序列的行为,让非序列引发适当的异常。

See the thing that's "evil" about type checking is not that you might want to behave differently for a certain type of object, it's that you artificially restrict your function from doing the right thing with unexpected object types that would otherwise do the right thing. If you have a final fallback that is not type-checked, you remove this restriction. It should be noted that too much type checking is a code smell that indicates that you might want to do some refactoring, but that doesn't necessarily mean you should avoid it from the getgo.

如果你只需要知道你是否可以对变量使用foo[123]符号,你可以用hasattr(foo, '__getitem__')检查是否存在__getitem__属性(这是python在通过索引访问时调用的属性)。