为了账号安全,请及时绑定邮箱和手机立即绑定

从被拦截的被调用方获取名称空间

从被拦截的被调用方获取名称空间

潇潇雨雨 2021-03-19 15:11:17
我想在执行Python代码时拦截异常并做一些报告。主要是我想在发生异常时导出代码的名称空间。我能做的是以下几点:我有test.py会引发异常的文件:for i in range(10):    if i > 5:        j    else:        icheck.py当测试脚本作为参数传递时,将拦截异常并启动调试器的文件:import sys, pdbtry:    __import__(sys.argv[1])except Exception as e:    pdb.post_mortem(sys.exc_info()[2])那很好。此外,我可以使用以下inspect模块在发生异常的被调用方中找到该框架:import sys, inspecttry:    __import__(sys.argv[1])except Exception as e:    callee_frame_tuple = inspect.trace()[1]    print callee_frame_tuple输出:(<frame object at 0x00C9B260>, 'C:\\Temp\\test.py', 3, '<module>', ['        j\n'], 0)并使用它来获取有关框架的信息getargvalues():import sys, inspecttry:    __import__(sys.argv[1])except Exception as e:    callee_frame_tuple = inspect.trace()[1]    inspect.getargvalues(callee_named_tuple[0])[3]['__builtins__']['locals']()输出:{'__builtins__': <module '__builtin__' (built-in)>, '__doc__': None, '__file__': 'C:\\Temp\\check.py', '__name__': '__main__', '__package__': None, 'e': NameError("name 'j' is not defined",), 'inspect': <module 'inspect' from 'C:\Python27\lib\inspect.pyc'>, 'sys': <module 'sys' (built-in)>}因此check.py,test.py尽管我将其帧引用用作getargvalues()参数,但我却为被调用方而不是被调用方提供了本地人。有人知道如何获取被调用方名称空间吗?
查看完整描述

1 回答

?
慕后森

TA贡献1802条经验 获得超5个赞

从格式化的追溯记录中还不清楚Python可以打印出什么,但是由于您正在使用__import__,所以实际上得到了两个单独的traceback对象。您可以像这样访问第二个...


import sys

from pprint import pprint


try:

    __import__(sys.argv[1])

except Exception as e:

    my_traceback = sys.exc_info()[2]


# Print locals for my stack frame

#pprint(my_traceback.tb_frame.f_locals)


# Print locals for other stack frame

other_traceback = my_traceback.tb_next

pprint(other_traceback.tb_frame.f_locals)

Python文档的3.2节中有关于traceback和frame对象的更多信息。

更新

那是与inspect.getargvalues(callee_named_tuple[0]) 上面相同的对象,因此当我深入研究时,我不知道那实际上是被呼叫者的本地人。

你是对的。我对inspect模块不是很熟悉-我倾向于traceback直接访问属性。

我期望我可以找到命名空间dict,其中i变量的值为6,然后发生异常,而这种方式我可以得到i=None。没有办法获取被调用者的名称空间吗?

我也注意到了。使用似乎有些奇怪__import__,因为使用时它可以正常工作execfile()。以下脚本...

import sys


try:

    execfile(sys.argv[1])

except Exception as e:

    the_value_of_i = sys.exc_info()[2].tb_next.tb_frame.f_locals['i']

    print 'The value of "i" was "%r"' % the_value_of_i

产量


The value of "i" was "6"


查看完整回答
反对 回复 2021-03-29
  • 1 回答
  • 0 关注
  • 166 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信