Python 异常的最佳实践?

创建异常的最佳实践是什么?我刚看到这个,我不知道我是该害怕,还是喜欢。我在书中多次读到,异常永远不应该包含一个字符串,因为字符串本身可以抛出异常。这是真的吗?

基本上,从我对脚本的理解来看,这样做是为了让所有内部 Python 库都有一个共同的错误消息格式(这是非常需要的) ,这样我就可以理解为什么放置错误消息字符串是一个好主意。(几乎每个方法都会抛出异常,因为完全不需要无效的通过)。

有关守则如下:

"""
Base Exception, Error
"""
class Error(Exception):
def __init__(self, message):
self.message = message


def __str__(self):
return "[ERROR] %s\n" % str(self.message)


def log(self):
ret = "%s" % str(self.message)
if(hasattr(self, "reason")):
return "".join([ret, "\n==> %s" % str(self.reason)])
return ret


class PCSException(Error):
def __init__(self, message, reason = None):
self.message = message
self.reason = reason
def __str__(self):
ret = "[PCS_ERROR] %s\n" % str(self.message)
if(self.reason != None):
ret += "[REASON] %s\n" % str(self.reason)
return ret

这只是冰山一角,但是谁能告诉我为什么这是个糟糕的主意?或者是否有更好的异常编码流程/样式。

64268 次浏览

我在书里读过好几次 例外永远不应该包含 因为字符串本身可以 抛出例外。任何真正的事实 这个?

什么?

请提供一个参考或链接到这一点。这是完全不真实的。

由于所有对象都可以抛出异常,因此该逻辑不能在异常中包含任何对象。

不,“ No string”在 Python 上下文中简直是疯了,也许您是在 C + + 上下文中阅读它的。


剪辑

很久以前(回到过去) ,您可以通过名称而不是通过实际的类引发 Python 异常。

raise "SomeNameOfAnExceptionClass"

情况不妙。但这是 没有,在异常中包含一个字符串。这是使用字符串而不是实际的类对象来命名异常。在2.5中,这仍然可以工作,但会收到一个弃用警告。

也许您会读到“不要使用字符串名称引发异常”

第一印象是,对于异常来说,代码太多了。

格式化异常应该在日志记录器配置中完成,日志记录本身也是如此。

它还重新定义了标准(和不推荐的)消息属性,并且不调用超类构造函数。(这可能会或可能不会破坏 Python 3.0的异常链,我还没有试过,因为我运行的是2.6)

大多数额外代码的功能可以通过 BaseException.args 实现,方法是将以下内容记录为“ message”:

'\n==> '.join(exception.args)

我认为,如果可以使用通用/惯用机制完成某些操作,那么在异常处理中尤其应该这样做。(例外情况是一种机制,用于向 穿过去应用程序层发送信号。)

就我个人而言,我尽量避免任何超越

class SomeException(Exception): pass

(免责声明: 回答主观,可能是问题的性质。)

健壮的异常处理(在 Python 中) ——我前段时间写的“ Python 异常的最佳实践”博客文章。你会发现它很有用。

博客中的一些要点:

永远不要使用异常进行流控制

异常情况存在异常: 不是 正常执行的一部分。

如果没有找到模式,可以考虑在返回 -1的字符串上使用“ find”,但是超过字符串末尾的索引将引发异常。没有找到字符串是正常执行。

在知道如何处理异常的级别处理异常

...

最好的地方是那段能处理异常的代码 一些例外情况,例如编程错误(例如 IndexError、 TypeError、, NameError 等)异常最好留给程序员/用户, 因为“处理”它们只会隐藏真正的错误。

始终询问“这是处理此异常的正确位置吗?”并小心捕获所有异常。

记录由代码引发的异常

...

考虑代码可能抛出的异常将对您有所帮助 编写更好、更安全、更封装的代码

我相信不要用字符串创建异常的建议来自于“ Learning Python”(O’Reilly)。在题为 字符串异常被删除!的章节中,它指出了(现在已经删除了)直接使用任意字符串创建异常的能力。

它给出的示例代码是:

myexc = "My exception string"
try:
raise myexc
except myexc:
print ('caught')

这是第四版(平装本)第858页。

class Error(Exception):
"""Base class for other exceptions"""
pass


class empty_string_error(Error):
"""Raised when the input value is too large"""
pass
while(1):
try:
if("Your Condition"):
raise empty_string_error
else:
print("OUTPUT")
except empty_string_error:
print("APT MESSAGE")
print(" ")
finally:
pint("Mandatory code")