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()) # 通過傳入參數來進行判斷