Python中实现参数类型检查的简单方法


Posted in Python onApril 21, 2015

Python是一门弱类型语言,很多从C/C++转过来的朋友起初不是很适应。比如,在声明一个函数时,不能指定参数的类型。用C做类比,那就是所有参数都是void*类型!void类型强制转换在C++中被广泛地认为是个坏习惯,不到万不得已是不会使用的。

Python自然没有类型强制转换一说了,因为它是动态语言。首先,所有对象都从Object继承而来,其次,它有强大的内省,如果调用某个不存在的方法会有异常抛出。大多数情况,我们都不需要做参数类型栓查,除了一些特殊情况。例如,某个函数接受一个str类型,结果在实际调用时传入的是unicode,测试过程中又没有代码覆盖到,这样问题就比较严重了。解决方法也很简单,借助Python的内省,很容易就能判断出参数的类型。但是每个地方都写检查代码会很累赘,何况它带来的实际价值并不高。一个好的解决方法是使用装饰器。

'''
 >>> NONE, MEDIUM, STRONG = 0, 1, 2
 >>>
 >>> @accepts(int, int, int)
 ... def average(x, y, z):
 ...   return (x + y + z) / 2
 ...
 >>> average(5.5, 10, 15.0)
 TypeWarning: 'average' method accepts (int, int, int), but was given
 (float, int, float)
 15.25
'''
def accepts(*types, **kw):
  """ Function decorator. Checks that inputs given to decorated function
  are of the expected type.

  Parameters:
  types -- The expected types of the inputs to the decorated function.
       Must specify type for each parameter.
  kw  -- Optional specification of 'debug' level (this is the only valid
       keyword argument, no other should be given).
       debug = ( 0 | 1 | 2 )

  """
  if not kw:
    # default level: MEDIUM
    debug = 1
  else:
    debug = kw['debug']
  try:
    def decorator(f):
      def newf(*args):
        if debug == 0:
          return f(*args)
        assert len(args) == len(types)
        argtypes = tuple(map(type, args))
        if argtypes != types:
          msg = info(f.__name__, types, argtypes, 0)
          if debug == 1:
            print >> sys.stderr, 'TypeWarning: ', msg
          elif debug == 2:
            raise TypeError, msg
        return f(*args)
      newf.__name__ = f.__name__
      return newf
    return decorator
  except KeyError, key:
    raise KeyError, key + "is not a valid keyword argument"
  except TypeError, msg:
    raise TypeError, msg

def info(fname, expected, actual, flag):
  """ Convenience function returns nicely formatted error/warning msg. """
  format = lambda types: ', '.join([str(t).split("'")[1] for t in types])
  expected, actual = format(expected), format(actual)
  msg = "'%s' method " % fname \
     + ("accepts", "returns")[flag] + " (%s), but " % expected\
     + ("was given", "result is")[flag] + " (%s)" % actual
  return msg

本质上讲,这也是一种运行时检查,但效果已经不错了。
更多有趣的装饰器的使用,可以参考这篇文章http://wiki.python.org/moin/PythonDecoratorLibrary

Python 相关文章推荐
跟老齐学Python之for循环语句
Oct 02 Python
python文件的md5加密方法
Apr 06 Python
python分治法求二维数组局部峰值方法
Apr 03 Python
python中for循环输出列表索引与对应的值方法
Nov 07 Python
Python后台开发Django会话控制的实现
Apr 15 Python
Pycharm中出现ImportError:DLL load failed:找不到指定模块的解决方法
Sep 17 Python
python中对_init_的理解及实例解析
Oct 11 Python
Win10下用Anaconda安装TensorFlow(图文教程)
Jun 18 Python
区分python中的进程与线程
Aug 13 Python
安装并免费使用Pycharm专业版(学生/教师)
Sep 24 Python
Python 3.9的到来到底是意味着什么
Oct 14 Python
python中scipy.stats产生随机数实例讲解
Feb 19 Python
python实现的jpg格式图片修复代码
Apr 21 #Python
在Python的Flask框架中使用日期和时间的教程
Apr 21 #Python
在Python的Flask框架下收发电子邮件的教程
Apr 21 #Python
在Python的Flask框架中实现全文搜索功能
Apr 20 #Python
Python的Flask框架中实现分页功能的教程
Apr 20 #Python
在Python的Flask框架中实现单元测试的教程
Apr 20 #Python
Python的Flask框架中实现登录用户的个人资料和头像的教程
Apr 20 #Python
You might like
PHP新手上路(六)
2006/10/09 PHP
PHP执行zip与rar解压缩方法实现代码
2010/12/05 PHP
2014年10个最佳的PHP图像操作库
2014/07/14 PHP
[原创]php获取数组中键值最大数组项的索引值
2015/03/17 PHP
简单的邮箱登陆的提示效果类似于yahoo邮箱
2014/02/26 Javascript
jQuery中html()方法用法实例
2014/12/25 Javascript
javascript中判断json的方法总结
2015/08/27 Javascript
jquery 全选、全不选、反选效果的实现代码【推荐】
2016/05/05 Javascript
浅谈jQuery添加的HTML,JS失效的问题
2016/10/05 Javascript
js实现文字跑马灯效果
2017/02/23 Javascript
js自定义Tab选项卡效果
2017/06/05 Javascript
JavaScript严格模式下关于this的几种指向详解
2017/07/12 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
jquery动态添加带有样式的HTML标签元素方法
2018/02/24 jQuery
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
vue+element创建动态的form表单及动态生成表格的行和列
2019/05/20 Javascript
微信小程序 SOTER 生物认证DEMO 指纹识别功能
2019/12/13 Javascript
关于引入vue.js 文件的知识点总结
2020/01/28 Javascript
基于JS+HTML实现弹窗提示是否确认提交功能
2020/06/17 Javascript
详解element-ui动态限定的日期范围选择器代码片段
2020/07/03 Javascript
jquery+ajax实现异步上传文件显示进度条
2020/08/17 jQuery
python开发的小球完全弹性碰撞游戏代码
2013/10/15 Python
python自动化测试之从命令行运行测试用例with verbosity
2014/09/28 Python
Python封装shell命令实例分析
2015/05/05 Python
Python实现的快速排序算法详解
2017/08/01 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
2018/01/11 Python
jupyter notebook清除输出方式
2020/04/10 Python
Pycharm学生免费专业版安装教程的方法步骤
2020/09/24 Python
Django 权限管理(permissions)与用户组(group)详解
2020/11/30 Python
玩具反斗城天猫官方旗舰店:享誉全球的玩具店
2017/10/10 全球购物
企业统计员岗位职责
2013/12/13 职场文书
纪念建党演讲稿范文
2014/01/13 职场文书
cf收人广告词
2014/03/14 职场文书
公司请假条格式
2014/04/11 职场文书
节能环保演讲稿
2014/08/28 职场文书
竞选学习委员演讲稿
2014/09/01 职场文书