有些从Java转过来的朋友,可能会比较怀念Java的异常定义,也就是说,可以在定义一个函数时,声明它可能抛出的异常。因为我几乎没有Java语言的使用经验(如果说会安装tomcat和Eclipse就算Java高手的话,那我是:P),意识不到这种方式的优点。曾经有很久忽略了它。但是在读过一些Python书籍后,我发现,这种异常声明对Python也是很有意义的。于是,我试着写了一个decorator 来实现这个功能。事实证明,Python里虽然没有语法级别的函数异常声明,但是实现这样的功能非常简单。以下是一个简单的示例:

   1 #-*- coding:utf-8 -*-
   2 
   3 class ExpCollFunction(object):
   4     def __init__(self, fun, *exps):
   5         self.exps = tuple(exps)
   6         self.fun = fun
   7     def __call__(self, *args):
   8         return self.fun (*args)
   9 
  10 class ExpInclude(object):
  11     def __init__(self, *exps):
  12         self.exps = []
  13         self.exps.extend(exps)
  14     def __call__(self, fun):
  15         return ExpCollFunction(fun, *self.exps)
  16 
  17 @ExpInclude(Exception)
  18 def foo():
  19     print "foo function"
  20     raise Exception()

ExpCollFunctionExpInclude类型是通用的,定义成一个独立的模块就可以使用。只要在定义某一个函数时,像示例中的foo一样,以ExpInclude修饰,并在ExpInclude的参数中传入这个函数可能抛出的异常类型即可。除了decorator ,这种还技巧得益于Python的另外两个语法,一个是对象的可调用接口__call__,一个是except可以捕获以tuple约束的一组异常类型。 例如,我在idle shell中这样执行代码:

   1 try:
   2     foo()
   3 except foo.exps:
   4     print "foo exception"

返回:

foo function

foo exception

另外,一个捕获自定异常的简单方法是,将自定义异常通过多继承的方式进行分类,这样,捕获时可以简单的截获某一种异常的子类,就像GMail里的邮件标签。这种方式可以参见Bjarne Stroustrup的《C++语言的设计与演化》。 无论在Python还是Java中,使用异常声明,要严格确认声明的异常列表与函数中可能抛出的异常正确对应,否则只会适得其反。

March_Liu/exception_declare (last edited 2009-12-25 07:09:38 by localhost)