在Python中,我如何确定对象是否可迭代?

2022-09-05 00:57:56

有没有这样的方法?到目前为止,我发现的唯一解决方案是致电isiterable

hasattr(myObj, '__iter__')

但我不确定这是多么万无一失。


答案 1
  1. 检查序列类型的工作,但它会在Python 2中的字符串上失败。我也想知道正确的答案,在那之前,这里有一种可能性(也适用于字符串):__iter__

     try:
         some_object_iterator = iter(some_object)
     except TypeError as te:
         print(some_object, 'is not iterable')
    

内置检查方法,或者在字符串的情况下检查方法。iter__iter____getitem__

  1. 另一种通用的pythonic方法是假设一个可迭代的,如果它在给定对象上不起作用,则优雅地失败。Python 词汇表:

Pythonic编程风格,通过检查对象的方法或属性签名来确定对象的类型,而不是通过与某个类型对象的显式关系(“如果它看起来像鸭子,嘎嘎叫像鸭子,它必须是鸭。通过强调接口而不是特定类型,精心设计的代码通过允许多态替换来提高其灵活性。鸭子类型避免使用 type() 或 isinstance() 进行测试。相反,它通常采用EAFP(比许可更容易请求宽恕)的编程风格。

...

try:
   _ = (e for e in my_object)
except TypeError:
   print my_object, 'is not iterable'
  1. 集合模块提供了一些抽象基类,这些基类允许询问类或实例是否提供特定功能,例如:

     from collections.abc import Iterable
    
     if isinstance(e, Iterable):
         # e is iterable
    

但是,这不会检查可通过 迭代的类。__getitem__


答案 2

鸭子打字

try:
    iterator = iter(the_element)
except TypeError:
    # not iterable
else:
    # iterable

# for obj in iterator:
#     pass

类型检查

使用抽象基类。他们至少需要Python 2.6,并且仅适用于新样式的类。

from collections.abc import Iterable   # import directly from collections for Python < 3.3

if isinstance(the_element, Iterable):
    # iterable
else:
    # not iterable

但是,更可靠一些,如文档所述:iter()

检查会检测注册为 Iterable 或具有方法的类,但不检测使用该方法进行迭代的类。确定对象是否可迭代的唯一可靠方法是调用 。isinstance(obj, Iterable)__iter__()__getitem__()iter(obj)