Python装饰器实现函数动态类型检查
时间:2022-07-26
本文章向大家介绍Python装饰器实现函数动态类型检查,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Python装饰器实现函数动态类型检查
函数动态类型检查的装饰器代码
import inspect
import functools
def typeHints(fn):
@functools.wraps(fn)
def wrap(*args, **kwargs):
sig = inspect.signature(fn)
params = sig.parameters
# 处理kwargs:字典
for k, v in kwargs:
param = params[k]
if param.annotation != inspect._empty and not isinstance(v, param.annotation):
raise TypeError('parameter {} requires {}, but got {}'.format(k, param.annotation, type(v)))
# 处理args:元组
for i, x in enumerate(args):
param = list(params.values())[i]
if param.annotation != inspect._empty and not isinstance(x, param.annotation):
raise TypeError('parameter {} requires {}, but got {}'.format(param.name, param.annotation, type(x)))
ret = fn(*args, **kwargs)
return ret
return wrap
@typeHints
def add(x: int, y: int) -> int:
return x + y
@typeHints
def add1(x, y:int) -> int:
return x + y
print(add(3, 5)) # 输出结果为8
print(add1(1, 2)) # 输出结果为3
类型检查主要使用了inspect库。本次代码运行环境是python3.5.2。inspect库的使用方法在下面介绍。
inspect模块
检查函数动态类型时,我们主要使用的是inspect库中的signature类,parameter类。可以使用help方法查看inspect的详细信息:
import inspect
help(inspect)
inspect库的源代码见:/home/clg/.pyenv/versions/3.5.2/lib/python3.5/inspect.py
这个库用来获取Python动态对象的有用信息,比如本次用到的注解。
Signature类
Signature是inspect模块的一个类,inspect模块的signature函数用来获取一个Signature对象,函数原型如下:
signature() - get a Signature object for the callable
Signature类有一个属性是OrderedDict类型的parameters,存储的是参数名称到参数对象(Parameter类的对象)的一个有序映射。
Parameter类
Parameter类的对象主要用来组成signature()返回的Signature对象的parameters属性。Parameter类有两个常用的属性:
- name :str 参数的名称
- annotation 参数的注解,如果没有注解,则annotation为
Parameter.empty
inspect模块示例
def add(x: int, y: int) -> int:
return x + y
import inspect
sig = inspect.signature(add)
print(sig.parameters)
print(sig.parameters['x'])
print(sig.parameters.values())
# 输出结果
OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)])
x:int
odict_values([<Parameter "x:int">, <Parameter "y:int">])
odict_values
类似于list,但是不支持下表操作,因此需要用list()
转化为list之后再做下表操作。
- scrapy回调函数传递参数
- python更新数据库脚本两种方法
- 使聊天机器人具有个性
- 遇到502错误,invalid request block size 解决方法
- python中json.loads,dumps,jsonify使用
- sqlalchemy和flask-sqlalchemy几种分页操作
- 一个 tflearn 情感分析小例子
- 前端js,后台python实现RSA非对称加密
- 运行mysql时,提示Table ‘performance_schema.session_variables’ doesn’t exist
- ODL应用开发之MD-SAL中级教程
- Sql参数是一个list的最佳实践
- MyBatis 配置输出日志,不输出SQL问题解决
- lombok让你提高代码整洁度的神器附教程及原理分析
- mvn编译的时候一个破错误,google只有3个结果maven : Failed to install metadata project Could not parse metadata maven-
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel 解决多库下的DB::transaction()事务失效问题
- laravel 实现上传图片到本地和前台访问示例
- laravel框架模型中非静态方法也能静态调用的原理分析
- Laravel 5.2 文档 数据库 —— 起步介绍
- laravel csrf排除路由,禁止,关闭指定路由的例子
- thinkphp框架类库扩展操作示例
- Laravel ORM 数据model操作教程
- Laravel框架基础语法与知识点整理【模板变量、输出、include引入子视图等】
- laravel 解决Eloquent ORM的save方法无法插入数据的问题
- laravel框架中控制器的创建和使用方法分析
- php 使用expat方式解析xml文件操作示例
- laravel利用中间件做防非法登录和权限控制示例
- laravel框架中表单请求类型和CSRF防护实例分析
- Yii框架getter与setter方法功能与用法分析
- laravel框架中视图的基本使用方法分析