Python函数的类型检查

    Python是一种非常动态的语言,函数定义中完全没有类型约束。这一点很多来自强约束语言,比如Java的朋友都很不适应。其实个人觉得这件事好坏并不绝对。但是,如果非要给Python的函数也加上参数类型约束,并非不可能——最多付出一些性能上的代价,没有免费的午餐嘛。
    这个方法并不神秘,只是利用了Python的函数修饰。也未必有多大意义——对于我个人,需要强类型约束的话,我可能更倾向于写一个C++扩展。只是一个小小的技巧练习:
class ArgsChecker(object):    "Decorator for function arguments's type checker"    def __init__(self, *types):        self.args_types = types
    def __call__(self, fun):        def foo(*args):            if len(args) != len(self.args_types):                raise TypeError("The function need %s arguments."%len(self.args_types))            for arg, ty in zip(args, self.args_types):                if type(arg) != ty and (not issubclass(type(arg), ty)):                    raise TypeError("The argument must be %s."%ty)            return fun(*args)        return foo使用起来很简单:
>>> pfoo("abc")abc>>> pfoo(23)Traceback (most recent call last):  File "", line 1, in     pfoo(23)  File "F:\source\tools\Utils.py", line 14, in foo    raise TypeError("The argument must be %s."%ty)TypeError: The argument must be .
    甚至,int和Long也是不兼容的:
>>> @ArgsChecker(int, int)def add(x, y):    return x + y
>>> add(12432, 23)12455>>> add(123L, 23)Traceback (most recent call last):  File "", line 1, in     add(123L, 23)  File "F:\source\tools\Utils.py", line 14, in foo    raise TypeError("The argument must be %s."%ty)TypeError: The argument must be .
    当然,如果要将其用在实际应用,还有很多可以扩展的地方,比如设定错误和警告级别(例如上例中的Long与Int之间的兼容),可选类型,可变参数列等,这就有待于有兴趣的朋友发掘了。据说Python的后继版本将会引入类型约束。不知道会是什么样子。在我看来,Python的动态能力是非常可贵的,类型约束应该尽可能以不影响动态能力为前提,个人认为Haskell的类型约束就做得很漂亮。