Python异常类的__str__方法缺失异常

0 投票
4 回答
1453 浏览
提问于 2025-04-18 17:44

有没有人知道怎么在Python的异常类的__str__函数中捕获异常吗?还有,怎么用pdb调试这个__str__函数?因为我发现当我在__str__函数里调用pdb.set_trace()或者设置断点时,它似乎不起作用。

下面是个示例代码:

class Ex(Exception):
    def __str__(self):
        raise KeyError('1')

raise Ex()

输出结果是

Traceback (most recent call last):
  File "./exex.py", line 10, in <module>
    raise Ex()
__main__.Ex

而我觉得输出应该是这样的

KeyError: '1'

如果我在raise KeyError('1')之前加上pdb.set_trace(),Python运行时并不会在pdb.set_trace()那里中断。那么,有人知道在Exception.__str__比较复杂的时候该怎么调试吗?


抱歉关于pdb.set_trace()的情况。它是有效的。不过,如果你忘了加import pdb,那么Python会稍微忽略这个异常,看起来就像pdb.set_trace()被忽略了一样。

而在pdb中设置断点仍然不起作用。

4 个回答

0

顺便提一下,我之前提到过一个Python的bug,这个bug至少让输出结果看起来不那么让人困惑:issue22836 .

这个问题还有一个修复方案,但遗憾的是到现在为止还没有合并进正式版本。

0

你不需要重写 __str__ 方法就能得到消息。只需这样做:

class Ex(Exception):
   pass

raise Ex('Key Error 1')

输出结果是:

Traceback (most recent call last):
  File "Untitled.py", line 4, in <module>
    raise Ex('Key Error 1')
__main__.Ex: Key Error 1
0

Python处理错误的方式有点特别,因为它在打印错误信息的时候。如果这个时候再出现其他错误,程序员会更加困惑。所以,Python会把这个新的错误“吞掉”,尽量做好它能做的事情。

为了让你自己更开心,建议你在写类的时候,确保__str__方法总是返回一个字符串。

0

我前几天也遇到了同样的问题。最后我把我异常的 __str__ 方法放在了一个 try/except 块里。大概是这样的:

import traceback

class ex(Exception):
    def do_str(self):
        return "ex: %s" % self.notexist

    def check_str(self):
        try:
            return self.do_str()
        except:
            traceback.print_exc()
            raise

    __str__ = check_str

raise ex()

当你运行它的时候,会打印出:

Traceback (most recent call last):
  File "t100.py", line 16, in <module>
    raise ex()
__main__.exTraceback (most recent call last):
  File "t100.py", line 9, in check_str
    return self.do_str()
  File "t100.py", line 5, in do_str
    return "ex: %s" % self.notexist
AttributeError: 'ex' object has no attribute 'notexist'

撰写回答