Search code examples
pythonfor-looptry-catchiterable

Loop head inside try-block in python


I define an iterable like this:

class MyClass:
    
    def __init__(self, arg):
        self.arg = arg
        
    def __iter__(self):       
        for item in self.arg:
            yield item

Unfortunately arg might be None. I wonder how to catch this in style. I can do:

def __iter__(self):
    if self.arg is None:
        return
    for item in self.arg:
        yield item

But this does not comply with python's EAFP style. Maybe this way:

def __iter__(self):
    try:
        for item in self.arg:
            yield item
    except TypeError:
        return

But this seems dangerous to me. Actually, my loop is much more involved and I do not want any other TypeErrors to pass unnoticed. Can I restrict the try-block to the head of the loop?


Solution

  • This depends on whether you consider arg being None to be an error.

    If it's a supported value that just means there's nothing to work on then checking for it and returning, as per your first solution, makes the most sense.

    If it should never be None and someone passing that in is an error then just let the exception happen. Or, my personal choice, check it and throw an exception in __init__ to say the caller passed an invalid argument. Exceptions happening earlier (at the time the invalid thing happened) feels better than them happening later once a bunch of other things are going on and it's harder to figure out.