python inspect signature-python 参数注解inspect

# 静态语言:编译过程中会检查,会发下问题

# 动态语言:只有在运行时才会发现问题

# 1 由于编译期间不做任何检查,直到运行期间我呢提才会暴露

# 2 函数使用者并不知道参数类型的时候,容易传错参数类型

# 函数注解:给函数的形参一个类型,并有指向的return值

# python3.5开始引入

# 可以用于第三方工具(如:pycharm)提示是否有return

# 3.6可以对变量进行注解,如:i:int = 3

def add(x:int, y:int) -> int: # 声明规范是整数相加,并不强制形参类型

"""

This is add function

:param x: int

:param y: int

:return: int

"""

return x + y

print(add(4, 10))

print(add(4.0, 5.0))

print(add("abc", "d"))

# 业务应用

# 检查实参类型

# __annotations__是一个字典,其中包括返回值类型的声明。

# inspect模块:提供回去对象信息的函数,可以检查函数和类、类型检查

# signature(callable)函数,可以获取签名(函数签名包含了一个函数的信息,包括:函数名、参数类型、函数所在的类和名称空间及其他信息)

import inspect

def add(x:int, y:int, *args, **kwargs) -> int:

"""

This is add function

:param x: int

:param y: int

:return: int

"""

return x + y

print("0 ", add.__annotations__) # 普通字典

sig = inspect.signature(add) # 拿到add函数签名((x:int, y:int, *args, **kwargs) -> int)

print("---------------------")

print(sig)

print("1 params: ", sig.parameters) # 返回OrderedDict(有序字典)

print("2 return: ", sig.return_annotation) # 返回值注解

print("3 ", sig.parameters["x"])

print("4 ", sig.parameters["x"].annotation) # 参数注解

print("5 ", sig.parameters["args"])

print("6 ", sig.parameters["args"].annotation) # 空类型 inspect._empty

print("7 ", sig.parameters["kwargs"])

print("8 ", sig.parameters["kwargs"].annotation) # 空类型 inspect._empty

# inspect模块

# inspect.isfunction(add) 是否是函数

# inspect.ismethod(add) 是否是类的方法

# inspect.isgenerator(add) 是否是生成器对象

# inspect.isgeneratorfunction(add) 是否是生成器函数

# inspect.isclass(add) 是否是类

# inspect.ismodule(inspect) 是否是模块

# inspect.isbuiltin(print) 是否是内建对象

# inspect模块 - parameter对象

# 保存在元组中,只读 OrderedDict([("x", ), ("y", ), ("args", ), ("kwargs", )])

# name 参数名

# annotation 参数注解,可能没有定义

# default 参数缺省值,可能没有定义

# empty 特殊的类,用来标记default属性或者注释annotation属性的空值

# kind 实参如何绑定到形参

# POSITIONAL_ONLY 值必须是位置参数提供

# POSITIONAL_OR_KEYWORD 值可以作为关键字或者位置参数提供

# VAR_POSITIONAL 可变位置参数,对应*args

# KEYWORD_ONLY keyword_only参数,对应*或者*args之后出现的非可变关键字参数

# VAR_KEYWORD 可变关键字参数,对应**kwargs

def add2(x, y:int=11, *args, z, t=10, **kwargs) -> int:

return x + y

sig = inspect.signature(add2)

print("================================")

print("1 ", sig)

print("2 params ", sig.parameters)

print("3 return ", sig.return_annotation)

for i, item in enumerate(sig.parameters.items()):

name, param = item

print(i+1, name, " ", param.annotation, " ", param.kind, " ", param.default)

print(param.default is param.empty, end=" ")

# 装饰器

from functools import wraps

def checker(fn):

@wraps(fn) # Decorator factory

def wrapper(*args, **kwargs):

# 检查实参

print(args, kwargs)

sig = inspect.signature(fn)

params = sig.parameters # 有序字典

# 位置参数检查

param_list = tuple(params.keys()) # 转换成有序的元组

for i, v in enumerate(args):

k = param_list[i] # 拿到key

if isinstance(v, params[k].annotation): # 根据key拿到注解

print(v, " is ", params[k].annotation)

else:

print(v, " is not ", params[k].annotation)

# 关键参数检查

for k,v in kwargs.items():

if isinstance(v, params[k].annotation):

print(v, " is ", params[k].annotation)

else:

errstr = "{} {} {}".format(v, "is not", params[k].annotation)

print(errstr)

raise TypeError(errstr) # 抛出异常

result = fn(*args, **kwargs)

return result

return wrapper

@checker

def add3(x:int, y:int=8) -> int:

return x + y

print("================================")

print(add3(4, y=5))

add3("abc", "bcd")

print(add3(4))

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值