Pythonic方式结合`for`和`try`块

时间:2015-05-05 14:25:07

标签: 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 other stuff

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

我不喜欢这使得我的for循环双嵌套只是因为我需要阻止异常中止循环。有没有办法压扁这段代码?

2 个答案:

答案 0 :(得分:5)

然后你应该做像

这样的事情
function markError(text, markup) {
   markup.push("<b style='color: red;'>");
   markup.push(text);
   markup.push("</b>")
};

然后将其称为

def iterate_safe(parse_me, message, action):
    for node in parse_me:
        try:
            action(node)
        except Exception as e:
            LogErrorMessage(message.fmt(e, node))

答案 1 :(得分:1)

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

而不是编写多个for - 循环,每个循环必须包含try / catch块,写入函数描述中必须完成的内容使用for - 循环 try / catch日志记录逻辑,编写一个装饰器以应用于它们周围的装饰器。这有点像glglgl的解决方案,但更多Pythonic(在我看来)。例如:

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

使用functools.wraps可以进一步改善这一点。

请注意,如果您的标准是&#34;尽可能少使用缩进级别,这可能看起来有点难看,&#34;它实际上是Pythonic;在编写装饰器时,没有办法避免相当多的缩进级别。

最后,请注意从Exception更改为StandardError,我仍然强烈建议。