Самый простой способ, уважающий задание Python duck typing , состоит в том, чтобы поймать ошибку (Python отлично знает, чего он ожидает от объекта, чтобы стать итератором):
class A(object):
def __getitem__(self, item):
return something
class B(object):
def __iter__(self):
# Return a compliant iterator. Just an example
return iter([])
class C(object):
def __iter__(self):
# Return crap
return 1
class D(object): pass
def iterable(obj):
try:
iter(obj)
return True
except:
return False
assert iterable(A())
assert iterable(B())
assert iterable(C())
assert not iterable(D())
Примечания:
__iter__
, если тип исключения один и тот же: в любом случае вы не сможете для итерации объекта. callable
существует как проверка, могу ли я также полагаться на утиную печать, чтобы поднять AttributeError
, если __call__
не определен для мой объект, но это не так для повторной проверки? Я не знаю ответа, но вы можете либо реализовать функцию I (и других пользователей), либо просто уловить исключение в вашем коде (ваша реализация в этой части будет похожа на написанную мной функцию), просто убедитесь, что вы изолируете создание итератора из остальной части кода, чтобы вы могли зафиксировать исключение и отличить его от другого TypeError
.