python null怎么表示_[Python] @NotNull装饰器如何写比较好?

要求具体到某个参数,那最好的办法自然是使用最新的语法annotations了,随手摘一段现在项目里的代码:

def _get_inner_function(f):

while hasattr(f, '__wrapped__'):

f = f.__wrapped__

return f

def _checktype(f):

_inner_f = _get_inner_function(f)

check_type_args = inspect.getfullargspec(_inner_f).annotations

if not check_type_args:

warnings.warn(UserWarning("Function " + repr(f) + " does not have annotations, checktype ignored."))

return f

@wraps(f)

async def _f(*args, **kwargs):

call_args = inspect.getcallargs(_inner_f, *args, **kwargs)

for k, v in list(call_args.items()):

if k in check_type_args:

call_args[k] = check_type(v, check_type_args[k])

return await f(**call_args)

return _f

注意_checktype这个注解在这里是用来修饰async函数的,可以自行去掉async和await。check_type是一个按规则检查类型并返回正确的值的函数,它在输入类型不符合规则的时候会抛出异常。这里使用的是 hubo1016/pychecktype 这里的实现,你也可以换成自己的实现,比如说仅仅检查是否为None。

使用方法类似于下面这样:

@_checktype

async def myfunc(self, param1: str, param2: (str, None), param3, param4: int = 0):

...

解释一下,_get_inner_function用来获取最内层的原始函数定义,这个利用了wraps修饰器在Python3最新版当中的特性,这就防止了其他装饰器对_checktype的功能造成干扰(不过也限定了其他装饰器不能修改传入参数)。annotations在Python中是函数的一部分,可以通过inspect中的函数等方法来获取,最后在装饰过的函数中比较传入的参数与注解,并进行必要的类型检查,就可以完成这个功能。链接中的check_type实现中,None值只能匹配None或者NoneType(None的类型),而不能匹配str、int等具体类型,也就实现了输入不能为None的要求。

如果要求返回值也有检查,原理也是一样的,返回值的注解可以在函数后用 -> ...的形式表述,它在annotations当中是以'return'为key的一个值。

当然这个装饰器只能在运行时检查,是没有静态检查的功能的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值