I would like to iterate over the outputs of an unknown function. Unfortunately I do not know whether the function returns a single item or a tuple. This must be a standard problem and there must be a standard way of dealing with this — what I have now is quite ugly.
x = UnknownFunction()
if islist(x):
iterator = x
else:
iterator = [x]
def islist(s):
try:
len(s)
return True
except TypeError:
return False
for ii in iterator:
#do stuff
The most general solution to this problem is to use
isinstancewith the abstract base classcollections.Iterable.You might also want to test for
basestringas well, as Kindall suggests.Now some people might think, as I once did, “isn’t
isinstanceconsidered harmful? Doesn’t it lock you into using one kind of type? Wouldn’t usinghasattr(x, '__iter__')be better?”The answer is: not when it comes to abstract base classes. In fact, you can define your own class with an
__iter__method and it will be recognized as an instance ofcollections.Iterable, even if you do not subclasscollections.Iterable. This works becausecollections.Iterabledefines a__subclasshook__that determines whether a type passed to it is an Iterable by whatever definition it implements.