python常用模块-inspect模块


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())  # 通过传入参数来进行判断

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM