我正在用Python编写一个类,部分代码处理服务器。因此,我需要处理像ExpiredSession或ConnectionError这样的异常。
我没有为每个try / except块编写异常处理代码,而是在类中有一个函数来处理异常。像这样的东西(在类定义中)
def job_a(self):
try:
do something
except Exception as e:
#maybe print the error on screen.
self.exception_handling(e)
def job_b(self):
try:
do something else
except Exception as e:
#maybe print the error on screen.
self.exception_handling(e)
def exception_handling(self,e):
if isInstanceOf(e,ExpiredSession):
#deal with expired session.
self.reconnect()
if isInstanceOf(e,ConnectionError):
#deal with connection error
else:
#other exceptions
我不确定这种代码是否会导致任何问题,因为我没有看到代码这样做。比如,可能的内存泄漏? (现在我注意到当我有越来越多的错误/异常时,内存使用量会增长(虽然很慢),最终我必须重新启动进程才能吃掉所有的回忆。不确定这是原因。
将异常传递给单个函数是一种好习惯吗?
答案 0 :(得分:3)
这是context manager的一个很好的用例。您可以看到一些使用上下文管理器进行错误处理的示例here。 contextmanager装饰器允许您以单个函数的形式简明地编写上下文管理器。这是一个简单的例子:
class Foo(object):
def meth1(self):
with self.errorHandler():
1/0
def meth2(self):
with self.errorHandler():
2 + ""
def meth3(self):
with self.errorHandler():
# an unhandled ("unexpected") kind of exception
""[3]
@contextlib.contextmanager
def errorHandler(self):
try:
yield
except TypeError:
print "A TypeError occurred"
except ZeroDivisionError:
print "Divide by zero occurred"
然后:
>>> x = Foo()
>>> x.meth1()
Divide by zero occurred
>>> x.meth2()
A TypeError occurred
with
语句允许您"卸载"错误处理到一个单独的函数中,您可以捕获异常并使用它们执行您喜欢的操作。在你的真实"函数(即执行工作但可能引发异常的函数),只需要with
语句而不是整个复杂的try / except语句块。
这种方法的另一个优点是,如果出现无法预料的异常,它将正常传播而无需额外的努力:
>>> x.meth3()
Traceback (most recent call last):
File "<pyshell#394>", line 1, in <module>
x.meth3()
File "<pyshell#389>", line 12, in meth3
""[3]
IndexError: string index out of range
另一方面,在您提出的解决方案中,异常已经在每个函数中捕获,并且实际的异常对象被传递给处理程序。如果处理程序出现意外错误,则必须手动重新加载它(并且甚至不能使用裸raise
来执行此操作)。使用上下文管理器,意外的异常具有普通行为,无需额外的工作。