如何在Python中创建一个减去最后一个堆栈帧的异常?

2024-10-03 21:33:52 发布

您现在位置:Python中文网/ 问答频道 /正文

但这是不可能的:

我试图写一个稍微有点微妙的行为的对象-这可能是一个好主意,也可能不是一个好主意,我还没有决定。在

我有这个方法:

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)) 

现在,当我创建这样的实例时:

^{pr2}$

我得到一个包含我的函数的stacktrace:

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,它表示某些事情看起来是可能的,尽管可能涉及其中。如果有更简单的方法,我很乐意听!否则我就暂时搁置这个想法。在


Tags: noinpyselfobjectfoolineattribute
2条回答

你不能篡改回溯对象(这是件好事)。你只能控制如何处理你已经拥有的。在

唯一的例外是:你可以

对于您的目的,方法似乎是第一个选项:从高于函数一个级别的处理程序重新引发异常。在

我再说一遍,这对您自己或任何使用您的模块的人都是有害的,因为它会删除有价值的诊断信息。如果无论出于什么理由,您都坚持要使您的模块成为专有的,那么让它成为一个C扩展会更有效率。在

您可以使用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)

相关问题 更多 >