【问题标题】:Type checking: an iterable type that is not a string类型检查:不是字符串的可迭代类型
【发布时间】:2013-11-13 01:42:21
【问题描述】:

为了更好地解释,考虑这个简单的类型检查器函数:

from collections import Iterable
def typecheck(obj):
    return not isinstance(obj, str) and isinstance(obj, Iterable)

如果objstr 以外的可迭代类型,则返回True。但是,如果objstr 或不可迭代类型,则返回False

有什么方法可以更有效地执行类型检查?我的意思是,检查obj 的类型以查看它是否不是str 然后再次检查它以查看它是否可迭代似乎有点多余。

我想过列出除 str 之外的所有其他可迭代类型,如下所示:

return isinstance(obj, (list, tuple, dict,...))

但问题是这种方法会遗漏任何其他未明确列出的可迭代类型。

那么...有什么更好的方法还是我在函数中给出的方法最有效?

【问题讨论】:

  • 这不是低效的。您可能有更重要的事情要担心。
  • @thefourtheye - 因为有时您需要检查某些内容是否可迭代但不是字符串。一个示例可以是展平嵌套列表的函数。您不希望其中的字符串也变平。
  • @iCodez:但是你想让 dicts 变平吗?还是文件?在这种特定情况下,专门检查列表似乎更合理。也就是说,在某些合法用例中,您希望接受一个字符串或一个字符串序列,并且您希望区分这两者。
  • 如果排除str,通常也应该排除unicode和buffer
  • @aIKid - 是的,我也不太喜欢isinstance(obj, (list, tuple, dict,...)) 解决方案。我只是好奇是否有任何方法可以做到这一点而无需两次调用isinstance。但现在我开始认为这实际上是最好的方法。

标签: python python-3.x typechecking


【解决方案1】:

python 2.x 中,检查 __iter__ 属性很有帮助(尽管并不总是明智的),因为可迭代对象应该具有此属性,但字符串没有。

def typecheck(obj): return hasattr(myObj, '__iter__')

缺点是 __iter__ 并不是真正的 Pythonic 方式:例如,某些对象可能实现 __getitem__ 但不是 __iter__

Python 3.x 中,字符串获得了__iter__ 属性,破坏了此方法。

您列出的方法是我所知道的 Python 3.x 中最有效的真正 Pythonic 方法:

def typecheck(obj): return not isinstance(obj, str) and isinstance(obj, Iterable)

有一种更快(更有效)的方法,即像在 Python 2.x 中一样检查__iter__,然后检查str

def typecheck(obj): return hasattr(obj, '__iter__') and not isinstance(obj, str)

这与 Python 2.x 中的警告相同,但要快得多。

【讨论】:

  • isinstance(u'foo', str) 返回False 仍然存在明显的问题,因此您最终会遇到与明确列出所有 not 字符串类型的类型相同的难题。作为一个快速破解,我想出了检查hasattr(thing, 'lower'),但它显然太晦涩了。
  • @tripleee - isinstance(u'foo', basestring) 在 Python 2.x 中发挥作用(unicodestr 子类 basestring
猜你喜欢
  • 1970-01-01
  • 2019-08-23
  • 2022-10-18
  • 2018-12-12
  • 2016-05-26
  • 2019-11-21
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多