首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何知道方法调用中可能抛出哪些异常?

如何知道方法调用中可能抛出哪些异常?
EN

Stack Overflow用户
提问于 2009-10-19 21:43:37
回答 5查看 21.2K关注 0票数 96

有没有办法(在编码时)知道在执行python代码时会出现哪些异常?

因为我不知道可能抛出哪种异常类型(阅读文档并不总是有帮助,因为很多时候可以从深层传播异常),所以我最终捕获了基本异常类90%的时间。并且很多时候文档没有更新或不正确)。

有没有某种工具可以检查这一点(比如通过读取Python代码和库)?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-10-20 06:15:18

我猜,由于缺乏静态类型规则,解决方案只能是不精确的。

我不知道一些检查异常的工具,但你可以想出你自己的工具来满足你的需求(这是一个尝试静态分析的好机会)。

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

假设x为以下程序:

代码语言:javascript
复制
x = '''\
if f(x):
    raise IOError(errno.ENOENT, 'not found')
else:
    e = g(x)
    raise e
'''

使用compiler包构建AST:

代码语言:javascript
复制
tree = compiler.parse(x)

然后定义一个Raise访问者类:

代码语言:javascript
复制
class RaiseVisitor(object):
    def __init__(self):
        self.nodes = []
    def visitRaise(self, n):
        self.nodes.append(n)

遍历AST采集Raise节点:

代码语言:javascript
复制
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",这对于快速的实际结果来说是很好的:)

票数 24
EN

Stack Overflow用户

发布于 2009-10-19 21:56:47

解决这个问题的正确工具是单元测试。如果你有由真实代码引发的异常,而单元测试没有引发,那么你需要更多的单元测试。

考虑一下这个

代码语言:javascript
复制
def f(duck):
    try:
        duck.quack()
    except ??? could be anything

duck可以是任何对象

显然,如果鸭子没有叫声,你可以有一个AttributeError,如果鸭子有叫声,你可以有一个TypeError,但它是不可调用的。您不知道duck.quack()可能会产生什么,甚至可能是DuckError或其他什么

现在假设你有这样的代码

代码语言:javascript
复制
arr[i] = get_something_from_database()

如果它引发了一个IndexError,你不知道它是来自arri还是来自数据库函数的内部。通常情况下,在哪里发生异常并不重要,而是发生了一些错误,没有发生您想要发生的事情。

一种方便的技术是捕获异常,也许还可以像下面这样重新处理异常

代码语言:javascript
复制
except Exception as e
    #inspect e, decide what to do
    raise
票数 15
EN

Stack Overflow用户

发布于 2009-12-12 08:02:32

到目前为止,没有人解释为什么你不能有一个完整的,100%正确的异常列表,所以我认为这是值得评论的。其中一个原因是函数是一流的。假设你有一个这样的函数:

代码语言:javascript
复制
def apl(f,arg):
   return f(arg)

现在,apl可以引发f引发的任何异常。虽然在core库中没有太多类似的函数,但任何使用列表理解和自定义过滤器、map、reduce等的函数都会受到影响。

文档和源代码分析器是这里唯一“严肃”的信息来源。只要记住他们不能做的事情。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1591319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档