inspect模块
-
-
获取源码
-
获取类或者函数的参数信息
-
# 判断模块、框架、类、函数的方法,和type返回的类型是一样的,只是这里是判断 inspect.getmodulename(path) 获取模块名称 inspect.ismodule(object) 是不是个模块 inspect.isclass(object) 是不是个类 inspect.ismethod(object) 是不是一个方法 inspect.isfunction(object) 是不是一个函数 inspect.isgeneratorfunction(object) 是不是一个生成器函数 inspect.isgenerator(object) 是不是一个生成器 inspect.iscoroutinefunction(object) 是不是一个协程函数 inspect.getsource(object) 获取对象的源码(并不会解析装饰器原码) inspect.getsourcelines(object) 代码块,每行一个元素,组成数组 # signature 类 函数的签名信息:它包含了了函数的函数名、它的参数类型,它所在的类和名称空间及其他信息 # signature.parameters 里面存放的是函数的参数注解和返回值注解,组成的有序字典 # 参数注解常用的方法有: empty 等同于inspect._empty表示一个参数没有被类型注释 name 参数的名称 default 参数的默认值,如果一个参数没有默认值,这个属性的值为inspect.empty annotation 参数的注解类型,如果参数没有定义注解,这个属性的值为inspect.empty kind 参数的类型 # 参数类型 _POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY # 位置参数_only _POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD # 位置或关键字参数 _VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL # 可变位置参数 _KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY # keyword-only参数 _VAR_KEYWORD = _ParameterKind.VAR_KEYWORD # 可变关键字参数 # 获取对象的参数签名 >>> import inspect >>> def add(x:int,y:int): ... return x+y >>> sig = inspect.signature(add) >>> params = sig.parameters >>> print(params) OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)]) >>> params['x'].annotation <class 'int'> # 如果没有定义x的参数注解,那么这里就是inspect._empty # 案例检查参数 import inspect import functools def check(fn): # 这个装饰器只能用于函数,不能用于类方法 @functools.wraps(fn) def warpper(*args, **kwargs): sig = inspect.signature(fn) # 获取fn的参数 params = sig.parameters # 有序字典,OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)]) values = list(params.values()) for i,j in enumerate(args): if values[i].annotation != inspect._empty and not isinstance(j, values[i].annotation): raise TypeError("you must input {}".format(values[i].annotation)) for k,v in kwargs.items(): if params[k].annotation != inspect._empty and not not isinstance(v,params[k].annotation): raise TypeError("you must input {}".format(params[k].annotation)) return fn(*args, **kwargs) return warpper @check def add(x:int,y:int): return x+y print(add(1,2)) # 实例传参的校验方法(这里不检查*args和**kwargs里面的参数,只针对__init__) def check_params_cls(func): self = func.pop('self') params_attr = inspect.getfullargspec(self.__init__.__func__).annotations # 获取该实例的签名信息 attr_dict = params_attr.annotations # 获取参数名称和类型组成的字典 if params_attr.args[1:]: # 获取传入的参数名称 for i in attr_dict.keys(): if not isinstance(func[i], attr_dict[i]): raise TypeError('you {} must input {}'.format(func[i], attr_dict[i])) else: logger.info('实例没有初始化参数,或者是通过不定长参数来进行传参的') class Car(): def __init__(self, car_name, car_v: int = 100, car_gas: int = 800, car_fuel: (int, float) = 0.5, *args, **kwargs): check_params_cls(locals()) # 通过传入参数来进行判断