测试变量是列表还是元组

2024-03-28 12:28:01 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

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


Tags: 方法字符串org算法http数据结构列表节点
3条回答

只要不是多余的,使用isinstance就没有错。如果一个变量只应该是一个列表/元组,那么记录这个接口,并像这样使用它。否则支票是完全合理的:

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

这种类型的检查确实有一些很好的用例,例如使用标准字符串startswith/endswith方法(尽管准确地说,这些方法是在CPython中用C实现的,使用显式检查来查看它是否是元组-有多种方法可以解决这个问题,如链接到的文章中所述)。

显式检查通常比尝试将对象用作容器并处理异常要好——这可能导致代码部分或不必要地运行时出现各种问题。

如果需要,可以使用isinstance。它有点邪恶,因为它排除了自定义序列、迭代器和您可能实际需要的其他东西。但是,有时如果有人传递字符串,则需要采取不同的行为。我倾向于显式检查strunicode,如下所示:

import types
isinstance(var, types.StringTypes)

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

许多人认为types模块已经过时,而只需直接检查对象的类型,因此如果您不想使用上面的模块,也可以显式检查strunicode,如下所示:

isinstance(var, (str, unicode)):

编辑:

更好的是:

isinstance(var, basestring)

结束编辑

在这两种情况中的任何一种之后,您都可以回到行为上,就好像得到了一个正常的序列,让非序列引发适当的异常。

看到关于类型检查的“邪恶”之处,并不是您可能希望对某一类型的对象有不同的行为,而是您人为地限制您的函数对意外的对象类型执行正确的操作,否则将执行正确的操作。如果您有一个未进行类型检查的最终回退,则删除此限制。应该注意的是,过多的类型检查是一种代码味道,它表明您可能需要进行一些重构,但这并不一定意味着您应该从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'

相关问题 更多 >