Python:如何告诉 for 循环从一个函数继续?

新手上路,请多包涵

有时我需要在 for 循环中使用以下模式。有时在同一个循环中不止一次:

 try:
    # attempt to do something that may diversely fail
except Exception as e:
    logging.error(e)
    continue

现在我看不到将其包装在函数中的好方法,因为它不能 return continue

 def attempt(x):
    try:
        raise random.choice((ValueError, IndexError, TypeError))
    except Exception as e:
        logging.error(e)
        # continue  # syntax error: continue not properly in loop
        # return continue  # invalid syntax
        return None  # this sort of works

如果我 return None 我可以:

 a = attempt('to do something that may diversely fail')
if not a:
    continue

但我认为这不公平。我想从 attempt 函数中将 for 循环告诉 continue (或伪造它)。

原文由 fmalina 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 720
2 个回答

Python 已经有一个非常好的构造来执行此操作并且它不使用 continue

 for i in range(10):
    try:
        r = 1.0 / (i % 2)
    except Exception, e:
        print(e)
    else:
        print(r)

不过,我不会嵌套更多,否则您的代码很快就会变得非常难看。

在您的情况下,我可能会做更多类似的事情,因为对单个函数进行单元测试要容易得多,而且 平面比嵌套更好

 #!/usr/bin/env python

def something_that_may_raise(i):
    return 1.0 / (i % 2)

def handle(e):
    print("Exception: " + str(e))

def do_something_with(result):
    print("No exception: " + str(result))

def wrap_process(i):
    try:
        result = something_that_may_raise(i)
    except ZeroDivisionError, e:
        handle(e)
    except OverflowError, e:
        handle(e) # Realistically, this will be a different handler...
    else:
        do_something_with(result)

for i in range(10):
    wrap_process(i)

请记住始终 捕获 特定 的异常。如果您不希望抛出 特定 异常,则继续处理循环可能不安全。

编辑以下评论:

如果你真的不想处理异常,我仍然认为这是一个坏主意,那么捕获所有异常( except: )而不是 handle(e) ,只是 pass 。此时 wrap_process() 将结束,跳过真正工作完成的 else: 块,你将进入你的下一个迭代 for -d5-8环形。

请记住, 错误不应该悄无声息地过去

原文由 johnsyweb 发布,翻译遵循 CC BY-SA 3.0 许可协议

异常的整个想法是它们在多个间接级别上工作,即,如果您在调用层次结构深处有错误(或任何其他 异常 状态),您仍然可以在更高级别捕获它并正确处理它。

在您的情况下,假设您有一个函数 attempt() 调用调用层次结构中的函数 attempt2() 和 attempt3() ,并且 attempt3() 可能会遇到异常状态,这会导致主循环终止:

 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

您甚至可以自己抛出一个虚拟异常,这只会导致循环终止,甚至不会被记录。

 def attempt3():
    raise JustContinueException()

原文由 Boaz Yaniv 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏