这是一个普遍的概念性问题,不确定它是否适用于SO,但我会试一试。
我遇到过以下几次的情况,我从未确定如何处理它。
我有几个函数在一些层次结构中相互调用。我想处理函数的错误输入,但有些函数永远不会直接调用其他函数。
例如,我有这个功能:
def getDataSourcesOfTypes(username, datatypes):
if len(datatypes) < 1:
raise ValueError("Please specify at least 1 datatype")
http = authorizeHttp(username)
...snip...
return data_sources_list
这称之为:
def authorizeHttp(username):
if not isinstance(username, str):
raise ValueError("Invalid username.")
credential_json = Database.getCredential(username)
...snip...
反过来又称之为:
def getCredential(username):
Database.connection.row_factory = sqlite.Row # @UndefinedVariable
cursor = Database.connection.cursor()
...snip...
result = cursor.fetchone()
if result is None:
raise LookupError("Username does not exist.")
else:
...snip...
现在,对于username
,我有几次抓住坏的机会(即不是字符串,不存在等)。在我调用最后一个函数之前,显然我无法捕获它没有出现在数据库中的错误,但是我可以在第一个函数中找到None
。
问题是:捕获异常的最佳位置在哪里?在层次结构最远的层面?你能尽快吗?
同样,我认为对于SO来说这可能是一个主观问题,但我真的很好奇被认为是最佳做法。
答案 0 :(得分:2)
有一般建议可供遵循。
except: pass
)except:
或except Exception:
else
和finally
这是关于异常处理的good article。 Python docs也有最佳做法。那个from the past(但仍然有有效的信息)。
考虑到捕捉它们的地方。嗯,这里有不同的可能性。
您不能在代码中的任何其他位置使用任何这些功能 在这种情况下,请注意这个问题,意图是“我需要通知用户出了什么问题。这就是全部”。在这种情况下,可以在最高级别捕获异常。
在代码中广泛使用这些函数时,您需要采用不同的方法。像你一样引发异常,并在这个地方捕获它们,如果这是一个理想的行为,可以做任何事情来恢复正常的程序执行。或者,有时需要重新加注异常。例如:
try:
credential_json = Database.getCredential(username)
except LookupError as le:
log.warning(le)
renew_token() # (example) try to fix the problem somehow
credential_json = Database.getCredential(username) # retry
# note, that the next possible LookupError is not handled here.
finally:
check_data(credential_json)
return credential_json
您正在编写可重用的代码。在这种情况下,它很复杂。一个 需要深入了解您的工作流程。你的代码必须 提供自定义异常,异常处理程序,这很容易 重写,控制返回值,提供后备等。
def function_with_handler(data, error_handler=_handler, *args, **kwargs):
try:
do_stuff()
except CustomError as such_problem:
# log.level(such_problem)
_handler(such_problem, data, *args, **kwargs)
此外,有时向fail_silently = True
添加选项实际上是个好主意。
阅读大型项目的源代码通常是一种很好的做法。例如,查看Django
处理exceptions的方式。
答案 1 :(得分:0)
作为一般规则,我说,最接近错误的真正来源,它可以(可能)得到适当的处理。如果这是一个错误的输入,那么在输入的级别(也许在路上链接它)。如果这是字典中缺失键的预期异常,则立即捕获它。等
但当然,还有更多内容。