Python:我怎么知道哪些异常可能会从方法调用中抛出?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (86)

有没有一种方法知道(在编码时)执行python代码时期望有哪些异常?由于我不知道可能引发哪种异常类型,所以我最终在90%的时间内捕获基类异常类(并且不要告诉我阅读文档,很多时候异常可以从深处传播出来,文档未更新或更正的次数)。有没有某种工具来检查这个?(如通过阅读Python代码和库)?

提问于
用户回答回答于

我想一个解决方案可能只是因为缺乏静态类型规则而不精确。

我并不知道有一些工具可以检查异常,但是你可以根据自己的需求提出自己的工具(这是一个很好的机会,可以与静态分析结合使用)。

作为第一次尝试,你可以编写一个函数来构建AST,查找所有Raise节点,然后尝试找出引发异常的常见模式(例如,直接调用构造函数)

让我们x成为以下程序:

x = '''\
if f(x):
    raise IOError(errno.ENOENT, 'not found')
else:
    e = g(x)
    raise e
'''

使用compiler包构建AST :

tree = compiler.parse(x)

然后定义一个Raise访客类:

class RaiseVisitor(object):
    def __init__(self):
        self.nodes = []
    def visitRaise(self, n):
        self.nodes.append(n)

并且走AST收集Raise节点:

v = RaiseVisitor()
compiler.walk(tree, v)

>>> print v.nodes
[
    Raise(
        CallFunc(
            Name('IOError'),
            [Getattr(Name('errno'), 'ENOENT'), Const('not found')],
            None, None),
        None, None),
    Raise(Name('e'), None, None),
]

你可以继续使用编译器符号表解析符号,分析数据依赖关系等。或者你可以推断,CallFunc(Name('IOError'), ...)“应该肯定意味着提高IOError”,这对于快速的实际结果是相当好的。

用户回答回答于

你应该只捕捉你将要处理的异常。

通过具体类型捕获所有异常是无稽之谈。你应该抓住你特定的异常可以处理。对于其他异常,你可以编写一个捕获“基本异常”的通用catch,记录它(使用str()函数)并终止你的程序(或者在崩溃的情况下执行其他适当的操作)。

如果你真的要处理所有的异常,并确定它们都不是致命的(例如,如果你在某种沙箱环境中运行代码),那么捕捉泛型BaseException的方法就符合你的目标。

如果库引用真的很差,并且在捕获系统异常时不重新抛出它自己的异常,唯一有用的方法是运行测试(也许将其添加到测试套件中,因为如果某件事没有记录,它可能会改变!) 。删除对你的代码至关重要的文件,并检查正在抛出什么异常。提供太多数据并检查产生的错误。

无论如何,你将不得不运行测试,因为即使通过源代码获取异常的方法存在,它也不会让你知道你应该如何处理这些异常。也许你应该显示错误消息“File needful.txt is not found!” 当你抓到IndexError?只有测试可以告诉。

扫码关注云+社区

领取腾讯云代金券