有些从Java转过来的朋友,可能会比较怀念Java的异常定义,也就是说,可以在定义一个函数时,声明它可能抛出的异常。因为我几乎没有Java语言的使用经验(如果说会安装tomcat和Eclipse就算Java高手的话,那我是:P),意识不到这种方式的优点。曾经有很久忽略了它。但是在读过一些Python书籍后,我发现,这种异常声明对Python也是很有意义的。于是,我试着写了一个decorator 来实现这个功能。事实证明,Python里虽然没有语法级别的函数异常声明,但是实现这样的功能非常简单。以下是一个简单的示例:
#-*- coding:utf-8 -*-
class ExpCollFunction(object):
def init(self, fun, *exps):
- self.exps = tuple(exps) self.fun = fun
def call(self, *args):
- return self.fun (*args)
class ExpInclude(object):
def init(self, *exps):
- self.exps = [] self.exps.extend(exps)
def call(self, fun):
return ExpCollFunction(fun, *self.exps)
@ExpInclude(Exception) def foo():
- print "foo function" raise Exception()
ExpCollFunction和ExpInclude类型是通用的,定义成一个独立的模块就可以使用。只要在定义某一个函数时,像示例中的foo一样,以ExpInclude修饰,并在ExpInclude的参数中传入这个函数可能抛出的异常类型即可。除了decorator ,这种还技巧得益于Python的另外两个语法,一个是对象的可调用接口call,一个是except可以捕获以tuple约束的一组异常类型。 例如,我在idle shell中这样执行代码: >>> try:
- foo()
except foo.exps:
- print "foo exception"
foo function foo exception
另外,一个捕获自定异常的简单方法是,将自定义异常通过多继承的方式进行分类,这样,捕获时可以简单的截获某一种异常的子类,就像GMail里的邮件标签。这种方式可以参见Bjarne Stroustrup的《C++语言的设计与演化》。 无论在Python还是Java中,使用异常声明,要严格确认声明的异常列表与函数中可能抛出的异常正确对应,否则只会适得其反。