我有解析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循环双嵌套只是因为我需要阻止异常中止循环。有没有办法压扁这段代码?
答案 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
,我仍然强烈建议。