结合'for'和'try'块的Python方法

结合'for'和'try'块的Python方法,python,python-3.x,Python,Python 3.x,我有解析JSON提要的代码 对于每个数组,我都有如下代码: for node in parse_me: # It's important that one iteration failing doesn't cause all iterations to fail. try: i = node['id'] # KeyError? function_that_needs_int (i) # TypeError? # possibly

我有解析JSON提要的代码

对于每个数组,我都有如下代码:

for node in parse_me:
    # It's important that one iteration failing doesn't cause all iterations to fail.
    try:
        i = node['id'] # KeyError?
        function_that_needs_int (i) # TypeError?
        # possibly other stuff

    except Exception as e:
        LogErrorMessage ('blah blah blah {} in node {}'.fmt(e, node))

我不喜欢因为需要阻止异常中止循环而使for循环双重嵌套。有没有办法把这段代码展平?

那么你应该做如下事情

def iterate_safe(parse_me, message, action):
    for node in parse_me:
        try:
            action(node)
        except Exception as e:
            LogErrorMessage(message.fmt(e, node))
然后像这样称呼它

def action(node):
    do_whatever_must_be_done_with(node)

iterate_safe(parse_me, action, 'blah blah blah {} in node {}')
iterate_safe(parse_me, other_action, 'spam ham {} in node {}')

EDIT:最初的问题似乎暗示整个解析操作在一个巨大的
for
循环中;我的答案已修改,以反映以下评论

不要为-循环编写多个
,每个循环都必须包含一个
try
/
catch
块,而是编写函数来描述必须在循环中执行的操作,并编写一个修饰符应用于循环,该修饰符将用
for
-循环和
try
/
catch
日志逻辑围绕每个循环。这有点像GLGL的解决方案,但有点像Python(在我看来)。例如:

def apply_to_nodes_and_log_errs(node_visit_func):
    def safe_iterating_visitor(nodes_to_parse):
        for node in nodes_to_parse:
            try:
                node_visit_func(node)
            except StandardError as e:
                LogErrorMessage ('blah blah blah {} in node {}'.fmt(e, node))
    return safe_iterating_visitor

@apply_to_nodes_and_log_errs
def action_one(node):
    # ... "lots of stuff" :D

@apply_to_nodes_and_log_errs
def action_two(node):
    # different stuff
如果你想把装饰师分成几块:

def iterate_over_nodelist(node_visit_func):
    def iterating_visitor(nodes_to_parse):
        for node in nodes_to_parse:
            node_visit_func(node)
    return iterating_visitor

def safely_visit_log_errs(node_visit_func):
    def safe_logging_visitor(node_to_visit):
        try:
            node_visit_func(node)
        except StandardError as e:
            LogErrorMessage ('blah blah blah {} in node {}'.fmt(e, node))
    return safe_logging_visitor

def apply_to_nodes_and_log_errs(node_visit_func):
    return iterate_over_nodelist(safely_visit_log_errs(node_visit_func))

# ... write visit functions
这一点可以进一步改进使用

请注意,如果您的标准是“使用尽可能少的缩进级别”,那么这看起来可能有点难看,但实际上它是相当python的;在编写decorator时,确实无法避免相当多的缩进级别


最后,请注意,将
异常
更改为
标准错误
,我仍然强烈建议这样做。

我觉得这很好,问题是什么?如果嵌套级别困扰您,这意味着是时候将内容移到自己的函数中了。@marounnaroun,“我需要阻止异常中止循环”@marounnaroun比较两段完全不一样的代码的“性感”似乎毫无意义。这看起来不错,但如果“#对节点做很多事情”很大,你应该为这部分代码创建一个方法。然后,您将决定是否在方法中加入try catch。从我的观点来看,在你的示例中使用一个方法和try-catch会很好。我用一个代码示例编辑了这个问题,该代码给出了一些问题。有时我们需要为
正文做大量的工作,但有时只是一两行。唯一一致的是,这种for循环的习惯用法一直在出现。我的错误主要源于JSON提要的数据错误。有时数据丢失或者我们得到奇怪的值(“12”在一个应该是int的字段中),通常我只是在未经测试的情况下结束。我在这个应用程序中看到的每个异常都是“数据出错”的异常,所以我现在不担心传递异常。如果我开始遇到异常,重新刷新是有意义的,我将开始重新刷新它们。@问题C那么你实际上有多个循环,而不是一个大循环?同样,键盘中断异常也是一个很好的例子;您不知道这些将在何时发生(不管您对代码的经验如何),并且您几乎应该总是重新引用它们。至少,捕获
标准错误
比捕获
异常
要好得多。这是用于基于JSON语法的解析器的。语法中的每个数组都使用类似于我在上面发布的
for:try:
块进行解析。因此,我们有尽可能多的循环,就像我们有格式中的集合一样。它读起来相当不错(代码基本上看起来像我们的业务需求),但是由于我们必须处理异常而产生的循环的双重嵌套非常烦人。@QuestionC我编辑了我的问题,以反映您正在使用多个循环。不过,请注意,
try
不是一个“循环”,因此无论如何实现,都不是真正的双嵌套循环。