从FrameInfo或python中的frame获取函数签名
在用python编写自己的异常钩子时,我想到了使用从FrameInfo或python中的frame获取函数签名,python,traceback,Python,Traceback,在用python编写自己的异常钩子时,我想到了使用inspect-模块来为自己提供有关如何调用函数的更多信息 这意味着函数的签名以及传递给它的参数 import inspect frame_infos = inspect.trace() # get the FrameInfos for f_idx, f_info in enumerate(frame_infos): frame_dict.update(f_info.frame.f_locals) # update namespace
inspect
-模块来为自己提供有关如何调用函数的更多信息
这意味着函数的签名以及传递给它的参数
import inspect
frame_infos = inspect.trace() # get the FrameInfos
for f_idx, f_info in enumerate(frame_infos):
frame_dict.update(f_info.frame.f_locals) # update namespace with deeper frame levels
#Output basic Error-Information
print(f' File "{f_info.filename}", line {f_info.lineno}, in {f_info.function}')
for line in f_info.code_context:
print(f' {line.strip()}')
########################################################
# show signature and arguments 1 level deeper
if f_idx+1 < len(frame_infos):
func_name = frame_infos[f_idx+1].function #name of the function
try:
func_ref = frame_dict[func_name] # look up in namespace
sig = inspect.signature(func_ref) # call signature for function_reference
except KeyError: sig = '(signature unknown)'
print(f' {func_name} {sig}\n')
print(f' {frame_infos[f_idx+1].frame.f_locals}\n')
输出:
File "C:/test/errorHandler.py", line 136, in <module>
test1(5)
test1 (x:int, y:tuple=0) -> list
{'y': 0, 'x': 5}
File "C:/test/errorHandler.py", line 130, in test1
return test2(y, b=x, help=0)
test2 (a, *args, b, **kwargs)
{'kwargs': {'help': 0}, 'args': (), 'b': 5, 'a': 0}
File "C:/test/errorHandler.py", line 133, in test2
return a + b / 0
Traceback (most recent call last):
File "C:/test/errorHandler.py", line 142, in <module>
try: foo(0, 1, test=True)
> foo (a, b, **kwargs)
-> 'b': 'fail'
File "C:/test/errorHandler.py", line 140, in foo
return 0 / 0
ZeroDivisionError: division by zero
文件“C:/test/errorHandler.py”,第136行,在
测试1(5)
test1(x:int,y:tuple=0)->list
{'y':0,'x':5}
文件“C:/test/errorHandler.py”,第130行,在test1中
返回test2(y,b=x,help=0)
测试2(a,*args,b,**kwargs)
{'kwargs':{'help':0},'args':(),'b':5,'a':0}
文件“C:/test/errorHandler.py”,第133行,在test2中
返回a+b/0
但是,一旦离开1个文件,就不能将函数名映射到基本名称空间
文件1:导入文件2;尝试:file2.foo()除了:…
文件2:
导入文件3;def foo():file3.foo()
文件3:
def foo():返回0/0
因此,本质上,我正在寻找一种从FrameInfo
或frame
-对象获取函数(如
)的方法,但我看到的唯一信息是名称、文件和行(我不喜欢通过查看源文件中特定行来获取签名的想法。) 到目前为止,最好的参考是,但我还没有找到有用的东西。基于,我找到了恢复签名的解决方案 使用
gc
(垃圾收集器)功能,可以搜索直接引用特定对象的所有对象
通过帧的f_code
提供的code对象,您可以使用此函数查找帧,也可以使用此函数查找帧
code_obj = frame.f_code
import gc #garbage collector
print(gc.get_referrers(code_obj))
# [<function foo at 0x0000020F758F4EA0>, <frame object at 0x0000020F75618CF8>]
现在可以在过滤对象上使用
Disclamer来自: 此函数将仅定位支持垃圾收集的容器;将找不到引用其他对象但不支持垃圾回收的扩展类型。
完整代码示例: 输出:
File "C:/test/errorHandler.py", line 136, in <module>
test1(5)
test1 (x:int, y:tuple=0) -> list
{'y': 0, 'x': 5}
File "C:/test/errorHandler.py", line 130, in test1
return test2(y, b=x, help=0)
test2 (a, *args, b, **kwargs)
{'kwargs': {'help': 0}, 'args': (), 'b': 5, 'a': 0}
File "C:/test/errorHandler.py", line 133, in test2
return a + b / 0
Traceback (most recent call last):
File "C:/test/errorHandler.py", line 142, in <module>
try: foo(0, 1, test=True)
> foo (a, b, **kwargs)
-> 'b': 'fail'
File "C:/test/errorHandler.py", line 140, in foo
return 0 / 0
ZeroDivisionError: division by zero
回溯(最近一次呼叫最后一次):
文件“C:/test/errorHandler.py”,第142行,在
try:foo(0,1,test=True)
>foo(a、b、**kwargs)
->“b”:“失败”
文件“C:/test/errorHandler.py”,第140行,在foo中
返回0/0
ZeroDivision错误:被零除
你不能相信这一点,但这是另一个问题的问题
链接: 以下是一些链接,如果你想自己研究:
def foo (a, b, **kwargs):
del a, kwargs
b = 'fail'
return 0/0
try: foo(0, 1, test=True)
except: ERROR_Printer_Inspection()
Traceback (most recent call last):
File "C:/test/errorHandler.py", line 142, in <module>
try: foo(0, 1, test=True)
> foo (a, b, **kwargs)
-> 'b': 'fail'
File "C:/test/errorHandler.py", line 140, in foo
return 0 / 0
ZeroDivisionError: division by zero