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采用getopt解析命令行输入参数实例
Sep 30 Python
python中二维阵列的变换实例
Oct 09 Python
Python爬虫的两套解析方法和四种爬虫实现过程
Jul 20 Python
python把1变成01的步骤总结
Feb 27 Python
python使用pygame模块实现坦克大战游戏
Mar 25 Python
利用Django模版生成树状结构实例代码
May 19 Python
python,Django实现的淘宝客登录功能示例
Jun 12 Python
python循环定时中断执行某一段程序的实例
Jun 29 Python
Python对列表的操作知识点详解
Aug 20 Python
pandas-resample按时间聚合实例
Dec 27 Python
如何基于线程池提升request模块效率
Apr 18 Python
Python -m参数原理及使用方法解析
Aug 21 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
常用表单验证类,有了这个,一般的验证就都齐了。
2006/12/06 PHP
使用adodb lite解决问题
2006/12/31 PHP
基于jQuery的弹出消息插件 DivAlert之旅(一)
2010/04/01 Javascript
js parseInt("08")未指定进位制问题
2010/06/19 Javascript
利用try-catch判断变量是已声明未声明还是未赋值
2014/03/12 Javascript
jQuery+css实现百度百科的页面导航效果
2014/12/16 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
jquery在ie7下选择器的问题导致append失效的解决方法
2016/01/10 Javascript
jQuery实现select模糊查询(反射机制)
2017/01/14 Javascript
十个免费的web前端开发工具详细整理
2017/09/18 Javascript
JavaScript实现打印星型金字塔功能实例分析
2017/09/27 Javascript
实时监控input框,实现输入框与下拉框联动的实例
2018/01/23 Javascript
layui 数据表格+分页+搜索+checkbox+缓存选中项数据的方法
2019/09/21 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
2019/12/09 Javascript
Pyhton中单行和多行注释的使用方法及规范
2016/10/11 Python
对numpy中的transpose和swapaxes函数详解
2018/08/02 Python
python json.loads兼容单引号数据的方法
2018/12/19 Python
Python+OpenCv制作证件图片生成器的操作方法
2019/08/21 Python
基于Python实现大文件分割和命名脚本过程解析
2019/09/29 Python
Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
2019/10/12 Python
python实现拉普拉斯特征图降维示例
2019/11/25 Python
宝塔面板成功部署Django项目流程(图文)
2020/06/22 Python
MATLAB数学建模之画图汇总
2020/07/16 Python
全球速卖通法国在线交易平台:AliExpress法国
2017/07/07 全球购物
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
意大利折扣和优惠券网站:Groupalia
2019/10/09 全球购物
荷兰时尚精品店:Labels Fashion
2020/03/22 全球购物
小学生成长感言
2014/01/30 职场文书
学生会干部自我鉴定2014
2014/09/18 职场文书
2015年世界粮食日演讲稿
2015/03/20 职场文书
幸福终点站观后感
2015/06/04 职场文书
远程教育学习心得体会
2016/01/23 职场文书
浅谈Python列表嵌套字典转化的问题
2021/04/07 Python
Mysql 如何实现多张无关联表查询数据并分页
2021/06/05 MySQL
Nginx四层负载均衡的配置指南
2021/06/11 Servers
python 多态 协议 鸭子类型详解
2021/11/27 Python