美文网首页Python基础
Python:函数参数类型检查

Python:函数参数类型检查

作者: 子休_ | 来源:发表于2018-02-03 23:35 被阅读981次

有一个很经典的笑话:

三个月之前,只有我和上帝知道这代码是干什么的。
现在,只有上帝知道了。

在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方法获取了funcSignature对象,然后使用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的学习-3

    1.Python的内置函数会检查出参数类型错误。比如数据类型错误检查的参数是isinstance。 2.Pytho...

  • Python:函数参数类型检查

    有一个很经典的笑话: 三个月之前,只有我和上帝知道这代码是干什么的。现在,只有上帝知道了。 在Python中,不知...

  • python 函数参数类型

    本文主要学习内容: python函数参数类型 python 的函数参数类型分为4种:1.位置参数:调用函数时根据函...

  • python--用装饰器做参数检查

    编写自定义python函数后,一般有一个参数检查过程,检查输入的参数是否是定义的类型,参数检查可以避免一些明显错误...

  • 利用装饰器强制函数上的类型检查

    场景:对函数参数进行强制类型检查。

  • Python函数

    Python函数格式:def函数名(参数): 函数体 *参数主要有以下4种类型:必传参数、关键字参数、默认参数、不...

  • Python 函数

    参数检查 使用了isinstance函数进行数据类型的检查 默认参数 例: 如果不写3默认函数power_n的参数为2

  • 类型注解

    一.函数注解 Python3.5 引入 对函数的参数进行类型注解 对函数的返回值进行类型注解 只对函数参数做一个辅...

  • E【1365】有多少小于当前数字的数字

    Python里的(array:list)->int 这个是函数定义,来标注参数类型和返回类型。 因为python ...

  • Python学习笔记(五)函数参数类型检查

    instance()的用法 语法: 其中,object是变量,classinfo是类型(int/float/boo...

网友评论

    本文标题:Python:函数参数类型检查

    本文链接:https://www.haomeiwen.com/subject/sgspzxtx.html