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以环状形式组合排列图片并输出的方法
Mar 17 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
Nov 01 Python
Python模拟脉冲星伪信号频率实例代码
Jan 03 Python
Python使用requests发送POST请求实例代码
Jan 25 Python
Python实现的堆排序算法示例
Apr 29 Python
完美解决Pycharm无法导入包的问题 Unresolved reference
May 18 Python
11个Python Pandas小技巧让你的工作更高效(附代码实例)
Apr 30 Python
elasticsearch python 查询的两种方法
Aug 04 Python
pytorch实现mnist分类的示例讲解
Jan 10 Python
Python 调用有道翻译接口实现翻译
Mar 02 Python
Python如何定义有可选参数的元类
Jul 31 Python
python如何修改文件时间属性
Feb 05 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
高分R级DC动画剧《哈莉·奎茵》第二季正式预告首发
2020/04/09 欧美动漫
让你的网站可编辑的实现js代码
2009/10/19 Javascript
用js替换除数字与逗号以外的所有字符的代码
2014/06/07 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
2015/01/28 Javascript
使用JQuery在线制作ppt并在线演示源码特效
2015/09/08 Javascript
jQuery点击改变class并toggle及toggleClass()方法定义用法
2015/12/11 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
2016/04/13 Javascript
JS简单实现仿百度控制台输出信息效果
2016/09/04 Javascript
BootStrap Tooltip插件源码解析
2016/12/27 Javascript
Bootstrap select下拉联动(jQuery cxselect)
2017/01/04 Javascript
微信小程序 开发之全局配置
2017/05/05 Javascript
layui获取选中行数据的实例讲解
2018/08/19 Javascript
微信小程序canvas拖拽、截图组件功能
2018/09/04 Javascript
浅谈webpack4 图片处理汇总
2018/09/12 Javascript
JS执行控制之节流模式实例分析
2018/12/21 Javascript
React中this丢失的四种解决方法
2019/03/12 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
2020/02/05 Javascript
[02:03]DOTA2亚洲邀请赛 HGT战队出场宣传片
2015/02/07 DOTA
一文总结学习Python的14张思维导图
2017/10/17 Python
python 构造三维全零数组的方法
2018/11/12 Python
对python中arange()和linspace()的区别说明
2020/05/03 Python
python 如何将office文件转换为PDF
2020/09/22 Python
Python collections.deque双边队列原理详解
2020/10/05 Python
python实现登录与注册系统
2020/11/30 Python
CSS3效果:自定义“W”形运行轨迹实例
2017/03/29 HTML / CSS
彼得罗夫美国官网:Peter Thomas Roth美国(青瓜面膜)
2017/11/05 全球购物
音乐系毕业生自荐信
2013/10/27 职场文书
大学军训感言
2014/01/10 职场文书
纺织工程专业推荐信
2014/09/08 职场文书
会议接待欢迎词范文
2015/01/26 职场文书
办公室岗位职责
2015/02/04 职场文书
小学音乐课歌曲《堆雪人》教学反思
2016/02/18 职场文书
python实现自动清理文件夹旧文件
2021/05/10 Python
python 中的@运算符使用
2021/05/26 Python
python识别围棋定位棋盘位置
2021/07/26 Python
Nginx使用ngx_http_upstream_module实现负载均衡功能示例
2022/08/05 Servers