Python中的函数参数类型检查

 更新时间:2022年12月19日 09:17:51   作者:子休_  
这篇文章主要介绍了Python中的函数参数类型检查,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 简单的Python解密rsa案例

    简单的Python解密rsa案例

    这篇文章主要为大家介绍了简单的Python解密rsa案例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • python使用 cx_Oracle 模块进行查询操作示例

    python使用 cx_Oracle 模块进行查询操作示例

    这篇文章主要介绍了python使用 cx_Oracle 模块进行查询操作,结合实例形式分析了Python使用cx_Oracle模块进行数据库的基本连接、查询、输出等相关操作技巧,需要的朋友可以参考下
    2019-11-11
  • python获得图片base64编码示例

    python获得图片base64编码示例

    这篇文章主要介绍了用python语言获得图片的Base64编码的示例,大家参考使用吧
    2014-01-01
  • Python查询IP地址归属完整代码

    Python查询IP地址归属完整代码

    这篇文章主要介绍了Python查询IP地址归属完整代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • 关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题

    关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题

    这篇文章主要介绍了关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • python 利用pyttsx3文字转语音过程详解

    python 利用pyttsx3文字转语音过程详解

    这篇文章主要介绍了python 利用pyttsx3文字转语音过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Python爬虫部分开篇概念讲解

    Python爬虫部分开篇概念讲解

    在学习Python爬虫部分,需要已经学过Python基础和前端的相关知识,本文对python爬虫概念及原理给大家详细介绍,需要的朋友跟随小编一起看看吧
    2021-04-04
  • Python实现手绘图效果实例分享

    Python实现手绘图效果实例分享

    在本篇文章里小编给大家整理了关于Python实现手绘图效果,有需要的朋友们可以学习下。
    2020-07-07
  • 浅析Python是如何实现集合的

    浅析Python是如何实现集合的

    之前我们介绍过字典的实现原理,它底层是基于哈希表实现的,而集合也是如此。本次我们来聊一下 Python 的集合是怎么实现的,希望对大家有所帮助
    2022-12-12
  • Python descriptor(描述符)的实现

    Python descriptor(描述符)的实现

    这篇文章主要介绍了Python descriptor(描述符)的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11

最新评论