To explain better, consider this simple type checker function:
from collections import Iterable
def typecheck(obj):
return not isinstance(obj, str) and isinstance(obj, Iterable)
If obj
is an iterable type other than str
, it returns True
. However, if obj
is a str
or a non-iterable type, it returns False
.
Is there any way to perform the type check more efficiently? I mean, it seems kinda redundant to check the type of obj
once to see if it is not a str
and then check it again to see if it is iterable.
I thought about listing every other iterable type besides str
like this:
return isinstance(obj, (list, tuple, dict,...))
But the problem is that that approach will miss any other iterable types that are not explicitly listed.
So...is there anything better or is the approach I gave in the function the most efficient?
In python 2.x, Checking for the __iter__
attribute was helpful (though not always wise), because iterables should have this attribute, but strings did not.
def typecheck(obj): return hasattr(myObj, '__iter__')
The down side was that __iter__
was not a truely Pythonic way to do it: Some objects might implement __getitem__
but not __iter__
for instance.
In Python 3.x, strings got the __iter__
attribute, breaking this method.
The method you listed is the most efficient truely Pythonic way I know in Python 3.x:
def typecheck(obj): return not isinstance(obj, str) and isinstance(obj, Iterable)
There is a much faster (more efficient) way, which is to check __iter__
like in Python 2.x, and then subsequently check str
.
def typecheck(obj): return hasattr(obj, '__iter__') and not isinstance(obj, str)
This has the same caveat as in Python 2.x, but is much faster.