Python: How to tell the for loop to continue from

2019-06-15 03:40发布

Sometimes I need the following pattern within a for loop. At times more than once in the same loop:

    try:
        var = 'attempt to do something that may fail on a number of levels'
    except Exception, e:
        log(e)
        continue

Now I don't see a nice way to wrap this in a function as it can not return continue:

def attempt(this):
    try:
        return this
    except Exception, e:
        log(e)
        # 1. continue # <-- syntax error: continue not properly in loop or
        # 2. return continue # <-- invalid syntax
        # 3.
        return False # <-- this sort of works, but makes me feel powerless

If I return False than I could:

    var = attempt('to do something that may fail on a number of levels')
    if not var:
        continue

But I don't feel that does it the justice. I want to tell the for loop to continue (or fake it) from within attempt function.

9条回答
可以哭但决不认输i
2楼-- · 2019-06-15 04:23

You could use this:

for l in loop:
  attempt() and foo(bar)

but you should make sure attempt() returns True or False.

Really, though, Johnsyweb's answer is probably better.

查看更多
一夜七次
3楼-- · 2019-06-15 04:24

The whole idea of exceptions is that they work across multiple levels of indirection, i.e., if you have an error (or any other exceptional state) deep inside your call hierarchy, you can still catch it on a higher level and handle it properly.

In your case, say you have a function attempt() which calls the functions attempt2() and attempt3() down the call hierarchy, and attempt3() may encounter an exceptional state which should cause the main loop to terminate:

class JustContinueException(Exception):
    pass

for i in range(0,99):
    try:
        var = attempt() # calls attempt2() and attempt3() in turn
    except JustContinueException:
        continue # we don't need to log anything here
    except Exception, e:
        log(e)
        continue

    foo(bar)

def attempt3():
    try:
        # do something
    except Exception, e:
        # do something with e, if needed
        raise # reraise exception, so we catch it downstream

You can even throw a dummy exception yourself, that would just cause the loop to terminate, and wouldn't even be logged.

def attempt3():
    raise JustContinueException()
查看更多
可以哭但决不认输i
4楼-- · 2019-06-15 04:26

Think that you are mapping foo on all items where attempt worked. So attempt is a filter and it's easy to write this as a generator:

def attempted( items ):
    for item in items:
        try:
            yield attempt( item )
        except Exception, e:
            log(e)

print [foo(bar) for bar in attempted( items )]
查看更多
登录 后发表回答