创建例外的最佳做法是什么?我刚看到这个,我不知道我是否应该感到恐惧或喜欢它。我在书中多次阅读异常永远不会持有字符串,因为字符串本身可以抛出异常。这有什么真相吗?
基本上我从脚本的理解是这样做,所以所有内部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
这只是冰山一角,但有人可以给我一些洞察力,让我知道这是一个多么糟糕的主意吗?或者,如果有更好的异常编码过程/风格。
答案 0 :(得分:82)
Robust exception handling (in Python) - 我之前写过的“Python异常的最佳做法”博客文章。您可能会发现它很有用。
博客中的一些要点:
永远不要使用流量控制的例外
特殊情况存在异常:不是a的事件 正常执行的一部分。
如果找不到模式,则在字符串上考虑'find',返回-1,但是超出字符串末尾的索引会引发异常。找不到字符串是正常执行。
处理知道如何处理它们的级别的异常
...
在 最好的地方是可以处理异常的那段代码。对于 一些例外,比如编程错误(例如IndexError,TypeError, NameError等)异常最好留给程序员/用户, 因为“处理”它们只会隐藏真正的错误。
总是问“这是处理此例外的正确位置吗?”并且要小心捕捉所有例外。
记录代码抛出的异常
...
考虑代码可能抛出的异常将对您有所帮助 写出更好,更安全,更封装的代码
答案 1 :(得分:32)
我在书中读了好几遍 例外永远不应该持有 字符串,因为字符串本身可以 抛出异常。任何真实的事实 此?
什么?
请提供参考或链接。这完全是不真实的。
由于所有对象都可以抛出异常,因此该逻辑不会在异常中包含任何对象。
不,“无字符串”在Python上下文中简直就是疯了。也许你是在C ++环境中阅读的。
修改强>
曾几何时(回到过去)你可以通过名称而不是实际的类来引发Python异常。
raise "SomeNameOfAnExceptionClass"
这很糟糕。但这是不,包括异常中的字符串。这是使用字符串而不是实际的类对象来命名异常。在2.5中,这仍然有效,但会收到弃用警告。
也许这就是您所读到的“不要使用字符串名称引发异常”
答案 2 :(得分:5)
我认为反对使用字符串创建异常的建议来自“学习Python”(O'Reilly)。在标题为 String Exceptions Are Right Out!的部分中,它指出了(现已删除)使用任意字符串直接创建异常的能力。
它给出的代码是:
myexc = "My exception string"
try:
raise myexc
except myexc:
print ('caught')
这是第四版的p858(平装本)。
答案 3 :(得分:4)
第一印象是异常的代码太多了。
格式化异常应在记录器配置中完成。记录本身也是如此。
它还重新定义了标准(和已弃用)消息属性,并且不调用超类构造函数。 (这可能会或可能不会破坏Python 3.0异常链接,我没有尝试,因为我正在运行2.6)
通过将以下内容记录为“消息”,可以使用BaseException.args实现额外代码的大部分功能:
'\n==> '.join(exception.args)
我认为如果可以使用通用/惯用机制来完成某些事情,那么在异常处理中尤其应该这样做。 (例外是一种在应用层之间发出信号的机制。)
就个人而言,我试图避免除
之外的任何事情class SomeException(Exception): pass
(免责声明:主观回答,可能是问题的性质。)
答案 4 :(得分:0)
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")