首页 > 编程语言 > 详细

python之装饰器强制函数上的类型检查

时间:2019-11-21 15:35:26      阅读:100      评论:0      收藏:0      [点我收藏+]

问题:通过装饰器想对函数参数进行强制类型检查,并且指定所有参数类型,也可以指定部分参数类型

未装饰的函数:

def spam(x, y, z=42):
    print(x,y,z)

spam(hello,1) #hello 1 42

写装饰器前,运用到了inspect中的signature签名函数,signature()获取函数的参数签名信息

sig = signature(spam)
print(sig) #(x, y, z=42)

print(type(sig.parameters[x].name)) #<class ‘str‘>
print(type(sig.parameters)) #<class ‘mappingproxy‘>
print(sig.parameters.items()) #odict_items([(‘x‘, <Parameter "x">), (‘y‘, <Parameter "y">), (‘z‘, <Parameter "z=42">)])
bind_partial() 方法来执行从指定类型到名称的部分绑定:
bound_types = sig.bind_partial(int,str,z=int) #允许忽略任何参数(int,z=int)
print(bound_types) #<BoundArguments (x=<class ‘int‘>, z=<class ‘int‘>)>
print(bound_types.arguments) #OrderedDict([(‘x‘, <class ‘int‘>), (‘z‘, <class ‘int‘>)])
print(bound_types.arguments[x]) #<class ‘int‘>

bind() 跟bind_partial() 类似,但是它不允许忽略任何参数:

bound_values = sig.bind(1,2,3) #不允许忽略任何参数
print(bound_values) #<BoundArguments (x=1, y=2, z=3)>
print(bound_values.arguments) #OrderedDict([(‘x‘, 1), (‘y‘, 2), (‘z‘, 3)])

 

了解完这些之后,开始实现该装饰器了~

 

下面是使用装饰器技术来实现 @typeassert

from inspect import signature
from functools import wraps

def typeassert(*ty_args,**ty_kwargs):
    def decorate(func):
        if not __debug__:
            return func

        sig = signature(func)
        bound_types = sig.bind_partial(*ty_args,**ty_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(str,z=int)
def spam(x, y, z=42):
    print(x,y,z)

spam(1,ds,www) #TypeError: Argument x must be <class ‘str‘>

 

 

 

python之装饰器强制函数上的类型检查

原文:https://www.cnblogs.com/Kerryworld/p/11905764.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!