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字符串替换示例
Apr 24 Python
Python基于二分查找实现求整数平方根的方法
May 12 Python
Python实现导出数据生成excel报表的方法示例
Jul 12 Python
基于Python代码编辑器的选用(详解)
Sep 13 Python
Python编写一个优美的下载器
Apr 15 Python
python中找出numpy array数组的最值及其索引方法
Apr 17 Python
Python实现的个人所得税计算器示例
Jun 01 Python
python基础梳理(一)(推荐)
Apr 06 Python
python安装scipy的方法步骤
Jun 26 Python
python爬取本站电子书信息并入库的实现代码
Jan 20 Python
Python计算信息熵实例
Jun 18 Python
Python中使用ipython的详细教程
Jun 22 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+MYSQL的文章管理系统(一)
2006/10/09 PHP
PHP is_dir() 判断给定文件名是否是一个目录
2010/05/10 PHP
php文件上传后端处理小技巧
2016/05/22 PHP
微信支付的开发流程详解
2016/09/13 PHP
Gambit vs CL BO3 第三场 2.13
2021/03/10 DOTA
jquery实现图片等比例缩放以及max-width在ie中不兼容解决
2013/03/21 Javascript
js 单击式的下拉菜单效果实例
2013/08/13 Javascript
js日期联动示例
2014/05/02 Javascript
JavaScript中string转换成number介绍
2014/12/31 Javascript
jquery实现表格本地排序的方法
2015/03/11 Javascript
详解JavaScript中的4种类型识别方法
2015/09/14 Javascript
学习Node.js模块机制
2016/10/17 Javascript
jQuery File Upload文件上传插件使用详解
2016/12/06 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
详解微信小程序 wx.uploadFile 的编码坑
2017/01/23 Javascript
jQuery替换节点元素的操作方法
2018/03/18 jQuery
为react组件库添加typescript类型提示的方法
2020/06/15 Javascript
[01:10]DOTA2亚洲邀请赛 征战号角响彻全场
2015/01/06 DOTA
Django卸载之后重新安装的方法
2017/03/15 Python
python图形工具turtle绘制国际象棋棋盘
2019/05/23 Python
django搭建项目配置环境和创建表过程详解
2019/07/22 Python
pyqt5 QScrollArea设置在自定义侧(任何位置)
2019/09/25 Python
Python turtle画图库&&画姓名实例
2020/01/19 Python
将python文件打包exe独立运行程序方法详解
2020/02/12 Python
日本非常有名的内衣丝袜品牌:GUNZE
2017/01/06 全球购物
Rentalcars.com中国:世界上最大的在线汽车租赁服务
2019/08/22 全球购物
都柏林通行卡/城市通票:The Dublin Pass
2020/02/16 全球购物
入党自我鉴定范文
2013/10/04 职场文书
会计学应届毕业生推荐信
2013/11/04 职场文书
酒吧员工的岗位职责
2013/11/26 职场文书
普罗米修斯教学反思
2014/02/06 职场文书
安全施工标语
2014/06/07 职场文书
党的群众路线教育实践活动对照检查材料
2014/09/22 职场文书
2014大学辅导员工作总结
2014/12/02 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
高考满分作文赏析(2篇)
2019/08/12 职场文书