Python中如何无goto实现紧急退出
在C语言中,我经常使用goto语句来从函数的中间跳出来,处理一些无法优雅解决的异常情况;比如关闭文件描述符,释放不再使用的内存,像这样:
error3:
for(j=0; j<i; j++) {
nameDelete(names[j]);
}
error:2
free(names);
error1:
close(fd);
error0:
exit(-1);
在我打开文件描述符之前,我会在error0:处跳出来,之后在error1:等地方跳出来,随着我获取资源的过程而变化。
而Python没有这种goto的写法。相反,我需要一个接一个地检查条件,每次都要重复写相应的代码。如果我在某个地方修改了函数以获取资源,我就得确保下面所有的提前退出都能正确处理这个资源,而不是在某个地方集中处理。
我并不执着于goto这种语法(我也读过Dijkstra的相关内容),但我在想在Python中有没有一种常见的模式可以用来处理这种操作。查阅《Python简明教程》并没有太大帮助。
[编辑]
我想避免的是:
try:
foo1
except:
bar0
try:
foo2
except:
bar0
try:
foo3
except:
bar1
try:
foo4
except:
bar2
在这里,bar2包含了bar2中的所有内容,而bar2又包含了bar0中的所有内容。我承认,bar#中很多内容可能会被垃圾回收机制处理,但我更喜欢谨慎一些,特别是在移植代码(这正是我正在做的)之前,我想先把它整理好。
4 个回答
我不太确定我是否完全理解你的需求,但听起来你可以使用 try ... except ... finally
这个结构。
想了解更多关于异常和异常处理的内容,可以在这里阅读:http://docs.python.org/tutorial/errors.html
如果你需要处理错误,可以使用异常。下面是来自官方Python手册的一个例子:
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
raise
顺便说一下,当需要的时候,你可以自己创建自定义的异常。
Python使用异常系统来处理这个问题:
raise Exception("ERROR")
当出现异常时,程序会不断“展开”并清理调用栈,直到异常被一个异常处理器“捕获”。如果异常没有被捕获,程序就会停止运行,打印出异常信息并退出。
想了解更多关于异常的内容,可以查看官方Python教程。
另外,你提到了资源的使用。这通常通过两种方式来实现:
- 初始化和清理,资源在初始化时分配,在释放时清理(方法
__init__
和__del__
) with
语句(方法__enter__
和__exit__
)
这两种方式在出现异常时都能正确地进行清理。