Python: inspect
import inspect def b(x, y: int = 5, *args, z, t=55, **kwargs) -> int: return x + y signature = inspect.signature(b) print(signature) print(signature.parameters) for i, (name, parameter) in enumerate(signature.parameters.items()): # name, parameter = item print(i + 1, name, parameter.annotation, parameter.kind, parameter.default) print(parameter.default is parameter.empty, end='\n' * 2)
print(x=5) 错在 x=5 是关键字传参, print函数没有定义x参数
import inspect, functools def discretion(fn): @functools.wraps(fn) def wrapper(*args, **kwargs): signature = inspect.signature(fn) parameters = signature.parameters # OrderedDict print(parameters) # OrderedDict([('x', < Parameter "x" >), ('y', < Parameter "y: int = 5" >), ('args', < Parameter "*args" >), ('z', < Parameter "z" >), ('t', < Parameter "t=55" >), ('kwargs', < Parameter "**kwargs" >)]) # for parameter in parameters.values(): # print(parameter.name,parameter.annotation,parameter.kind,parameter.default) # 找到没有显式传递的默认值参数 ******* args, kwargs 不可能有默认值 # def b(x, y: int = 5, *args, z=55, t, **kwargs): pass # 传递的默认值参数: 1. position 2. keyword only keys = tuple(parameters.keys()) default_parameters = list(keys) # 所有默认形参 print(f'keys: {keys}') print(f'args: {args}') print(f'kwargs: {kwargs}') # position arguments for i, v in enumerate(args): name = keys[i] default_parameters.remove(name) if parameters[name].annotation is inspect._empty: continue # 类型为空, 跳过检查 if isinstance(v, parameters[name].annotation): print(f'name: {name}, value: {repr(v)}, type: {parameters[name].annotation}') else: raise TypeError(f'value {repr(v)} is not type {parameters[name].annotation}') # keyword arguments for k, v in kwargs.items(): # Refactor -> Extract Method 提取公共方法 default_parameters.remove(k) if parameters[k].annotation is parameters[k].empty: continue if isinstance(v, parameters[k].annotation): print(f'name: {k}, value: {repr(v)}, type: {parameters[k].annotation}') else: raise TypeError(f'value {repr(v)} is not type {parameters[k].annotation}') # filter parameter using default if 'args' in default_parameters: default_parameters.remove('args') if 'kwargs' in default_parameters: default_parameters.remove('kwargs') for parameter in default_parameters: print(f'parameter {parameter} using default value {parameters[parameter].default}') ret = fn(*args, **kwargs) return ret return wrapper @discretion def b(x: int, y: str = '5') -> None: print(x, y) # b('5', 5) # b(4) # y有默认值, discretion没做检查 # b(4, '5') @discretion def p(x, y: int = 5, *args, z=55, t, **kwargs): print(f'x: {x}, y: {y}, args: {args}, z: {z}, t: {t}, kwargs: {kwargs}') # p(555, 22, 33, t=666) # x: 555, y: 22, args: (33,), z: 55, t: 666, kwargs: {} p(555, t=666) # keys: ('x', 'y', 'args', 'z', 't', 'kwargs') # args: (555,) # kwargs: {'t': 666}
import inspect def b(x, y: int = 55, *args, z=5, t, **kwargs): return 5 signature = inspect.signature(b) for name, parameter in signature.parameters.items(): print(list(signature.parameters.keys())) print(name, parameter.annotation) class B: print(__qualname__) print(__name__) B() def p(): print(inspect.stack()[0].filename) print(inspect.stack()[0].index) print(inspect.stack()[0].frame) print(inspect.stack()[0].function) print(inspect.stack()[0].code_context) print(inspect.stack()[0].lineno) for v in inspect.stack(): print(v, '\n', type(v)) print(v.function, type(v.function)) p()
import inspect def myself(): for frame_info in inspect.stack(): print('~' * 60) print(frame_info) print(type(frame_info)) print('~' * 60) for v in frame_info: print(type(v), v) print('#' * 60) return inspect.stack()[1][3] myself()
import inspect, functools def discretion(fn): @functools.wraps(fn) def wrapper(*args, **kwargs): signature = inspect.signature(fn) parameters = signature.parameters # OrderedDict([('x', <Parameter "x">), ('y', <Parameter "y: int = 7">), ('args', <Parameter "*args">), ('z', <Parameter "z=10">), ('t', <Parameter "t">), ('kwargs', <Parameter "**kwargs">)]) # POSITIONAL_ONLY = _POSITIONAL_ONLY # POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD # VAR_POSITIONAL = _VAR_POSITIONAL # KEYWORD_ONLY = _KEYWORD_ONLY # VAR_KEYWORD = _VAR_KEYWORD # print(parameters) keys = tuple(parameters.keys()) default_parameters = list(keys) print(f'keys: {keys}') print(f'args: {args}') print(f'kwargs: {kwargs}') print('~' * 80) # positional print('{0}Dispose Positional Arguments{0}'.format('*' * 20)) print() for i, v in enumerate(args): name = keys[i] if str(parameters[name].kind) == 'VAR_POSITIONAL': # 进行到了*args, 此时参数name是VAR_POSITIONAL, 被*args收集, 暂不支持参数类型检查, type(parameters[name].kind) 不是 str break default_parameters.remove(name) # 移除位置参数 print('-->', 'removing', name, '-->', 'default_parameters:', default_parameters) if parameters[name].annotation is parameters[name].empty: continue if isinstance(v, parameters[name].annotation): print(f'--> passed --> name: {name}, value: {repr(v)}, type: {parameters[name].annotation}') else: raise TypeError(f'value {repr(v)} is not type {parameters[name].annotation}') print('~' * 80) # keyword print('{0}Dispose Keyword Arguments{0}'.format('*' * 20)) print() for k, v in kwargs.items(): default_parameters.remove(k) print('-->', 'removing', k, '-->', 'default_parameters:', default_parameters) if parameters[k].annotation is parameters[k].empty: continue if isinstance(v, parameters[k].annotation): print(f'--> passed --> name: {k}, value: {repr(v)}, type: {parameters[k].annotation}') else: raise TypeError(f'value: {repr(v)} is not type {parameters[name].annotation}') print('~' * 80) print('after dispose positional and keyword arguments, default_parameters:', default_parameters) for name in default_parameters: if str(parameters[name].kind) in ('VAR_POSITIONAL', 'VAR_KEYWORD'): default_parameters.remove(name) print('after removing default_parameters:', default_parameters) print('~' * 80) return fn(*args, **kwargs) return wrapper @discretion def vet(x, /, y: int = 7, *args, z=10, t: int, **kwargs) -> int: print(f'x: {x}, y: {y}, args: {args}, z: {z}, t: {t}, kwargs: {kwargs}') return 5 vet(555, 22, 33, 44, 55, t=666)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律