Python中的函数参数类型检查
作者:子休_ 发布时间:2023-10-15 20:41:05
Python函数参数类型检查
有一个很经典的笑话:
三个月之前,只有我和上帝知道这代码是干什么的。
现在,只有上帝知道了。
在Python中,不知道函数参数类型是一个很正常的事情,特别是在一个大项目里。
我见过有些项目里,每一个函数体的前十几行都在检查参数类型,这实在是太麻烦了。而且一旦参数有改动,这部分也需要改动。
下面我们用装饰器来实现
函数参数的强制类型检查。
首先,这个装饰器,要接受类型参数,和指定函数参数的类型参数。也就是一个list和一个dict
from functools import wraps
def typeassert(*type_args, **type_kwargs):
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorate
@wraps(func)的作用请看我的另一篇
那么,接下来,在装饰器中,我们需要获取函数参数列表,并且要和类型参数表映射。
这要借助Python的一个标准库——inspect 这个库一般用于Python代码调试
from inspect import signature
from functools import wraps
def typeassert(*type_args, **type_kwargs):
def decorate(func):
sig = signature(func)
bound_types = sig.bind_partial(*type_args, **type_kwargs).arguments
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorate
上面的代码中,我们使用inspect中的signature方法获取了func的Signature对象,然后使用bind_partial方法创建了(*type_args, **type_kwargs)到func参数的映射(也就是一个字典)。
接下来就简单了,我们只需要再获取(*args, **kwargs)的类型,使用isintance函数进行比较就好。
from inspect import signature
from functools import wraps
def typeassert(*type_args, **type_kwargs):
def decorate(func):
sig = signature(func)
bound_types = sig.bind_partial(*type_args, **type_kwargs).arguments
@wraps(func)
def wrapper(*args, **kwargs):
bound_values = sig.bind(*args, **kwargs)
for name, value in bound_values.arguments.items():
if name in bound_types:
if not isinstance(value, bound_types[name]):
raise TypeError('Argument {} must be {}'.format(name, bound_types[name]))
return func(*args, **kwargs)
return wrapper
return decorate
运行如下代码
@typeassert(int, int)
def add(x, y):
return x+y
print(add("u", 2))
能看到报错如下
Traceback (most recent call last):
File "c:\Users\Chen\Desktop\typeassert.py", line 32, in <module>
print(add("u", 2))
File "c:\Users\Chen\Desktop\typeassert.py", line 22, in wrapper
'Argument {} must be {}'.format(name, bound_types[name])
TypeError: Argument x must be <class 'int'>
很贴心的提醒了我们哪一个参数应该是什么类型。
你甚至可以自己改动这个装饰器,让它还能告诉你传进去了什么错误参数(特别是写爬虫的时候,参数很难掌握,一旦报错,还得重跑一遍才知道为什么。)
你也可以指定某一个参数的类型,譬如
@typeassert(int, z=str)
def display(x, y, z):
print(x, y, z)
这时你会发现,y的类型就像原生的Python函数一样,什么都行。而x必须是int,z必须是str。
来源:https://www.jianshu.com/p/7a2c9133a002


猜你喜欢
- 代码'########### '检测远程文件是否存在 '########### function CheckURL(
- 这次讨论一下关于select元素的一个问题,其实很早以前我就碰到过关于select元素的问题,这次做网站又被问到同样的问题,就是:一般div
- 本文实例讲述了Python的批量远程管理和部署工具Fabric用法。分享给大家供大家参考。具体如下:Fabric是Python中一个非常强大
- Session和Cookie在Web开发中,Session和Cookie是常见的两种技术,它们用于在客户端和服务器端之间传递数据。Sessi
- 多表查询使用单个select 语句从多个表格中取出相关的查询结果,多表连接通常是建立在有相互关系的父子表上;1交叉连接第一个表格的所有行 乘
- Tuple概述在Python中使用元组(Tuple)存储一组信息,其特征如下:1、使用()定义元组2、元组中使用逗号 , 分割各元素;各元素
- 本文实例讲述了Python实现求解括号匹配问题的方法。分享给大家供大家参考,具体如下:这个在本科学习数据结构的时候已经接触很多了,主流的思想
- 想要asp能连接mysql数据库需要安装MySQL ODBC 3.51 驱动 http://www.jb51.net/softs/19910
- 前言有一天朋友A向我抱怨,他的老板要求他把几百份word填好的word表格简历信息整理到excel中,看着他一个个将姓名,年龄……从word
- 如何在本地机器上创建缓存?用法到是很简单,只需先创建Stream对象的实例,然后开始写入数据即可: Dim str&n
- 本文讲述了python提示No module named images的解决方法,非常实用!分享给大家供大家参考。具体方法如下:出现提示:I
- 我搜集了国内10几个电影网站的数据,里面近几十W条记录,用文本没法存,mongodb学习成本非常低,安装、下载、运行起来不会花你5分钟时间。
- 一、慢查询日志概念对于SQL和索引的优化问题,我们会使用explain去分析SQL语句。但是真正的企业级项目有成千上万条SQL,我们不可能从
- javascript cookie的基本操作(添加和删除)1.添加一个cookie:response.addCookie(Cookie c)
- 我将示范微优化(micro optimization)如何提升python代码5%的执行速度。5%!同时也会触怒任何维护你代码的人。但实际上
- 本文实例讲述了javascript设置和获取cookie的方法。分享给大家供大家参考,具体如下:1. 设置cookiefunction se
- 误区 #20:在破坏日志备份链之后,需要一个完整备份来重新开始日志链 错误 事务日志备份会备份自上次事务日志备份以来所有的事务日志(如果从来
- 新建两张表:表1:student 截图如下:表2:course 截图如下:(此时这样建表只是为了演示连接SQL语句,
- 本文实例为大家分享了vue无缝滚动组件vue-seamless-scroll的具体实现代码,供大家参考,具体内容如下下载cnpm i -S
- clear()方法将删除字典中的所有项目(清空字典)语法以下是clear()方法的语法:dict.clear()参数