不确定这是多么可能,但这里有:
我正在尝试用一些稍微微妙的行为来写一个对象 - 这可能是也可能不是一个好主意,我还没有确定。
我有这个方法:
def __getattr__(self, attr):
try:
return self.props[attr].value
except KeyError:
pass #to hide the keyerror exception
msg = "'{}' object has no attribute '{}'"
raise AttributeError(msg.format(self.__dict__['type'], attr))
现在,当我像这样创建一个这样的实例时:
t = Thing()
t.foo
我得到一个包含 my 函数的堆栈跟踪:
Traceback (most recent call last):
File "attrfun.py", line 23, in <module>
t.foo
File "attrfun.py", line 15, in __getattr__
raise AttributeError(msg.format(self._type, attr))
AttributeError: 'Thing' object has no attribute 'foo'
我不希望这样 - 我希望堆栈跟踪读取:
Traceback (most recent call last):
File "attrfun.py", line 23, in <module>
t.foo
AttributeError: 'Thing' object has no attribute 'foo'
这是否可以用最少的努力,或者是否需要很多种类?我发现this answer表明看起来有可能,尽管可能涉及到了。如果有一种更简单的方法,我很乐意听到它!否则我现在就把这个想法放在架子上。
答案 0 :(得分:3)
你不能篡改追溯对象(这是一件好事)。你只能控制你处理的方式。
唯一的例外是:你可以
raise e
重新提出一个例外(即将追溯点指向重新加注语句的位置)tb_next
property(这反映了追溯对象的洋葱状结构)出于您的目的,前进的方式似乎是第一个选项:从功能上方一级处理器重新引发异常。
而且,我会再次这样说,这对您自己或任何将使用您的模块的人都有害,因为它会删除有价值的诊断信息。如果你已经决定使你的模块具有任何基本原理的专有权,那么将它作为C扩展的目标更有效率。
答案 1 :(得分:0)
您可以使用 inspect 模块获取当前帧和任何其他级别。例如,当我想知道我在代码中的位置时,我会使用以下内容:
from inspect import currentframe
def get_c_frame(level = 0) :
"""
Return caller's frame
"""
return currentframe(level)
...
def locate_error(level = 0) :
"""
Return a string containing the filename, function name and line
number where this function was called.
Output is : ('file name' - 'function name' - 'line number')
"""
fi = get_c_frame(level = level + 2)
return '({} - {} - {})'.format(__file__,
fi.f_code,
fi.f_lineno)