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