有没有办法(在编码时)知道在执行python代码时会出现哪些异常?
因为我不知道可能抛出哪种异常类型(阅读文档并不总是有帮助,因为很多时候可以从深层传播异常),所以我最终捕获了基本异常类90%的时间。并且很多时候文档没有更新或不正确)。
有没有某种工具可以检查这一点(比如通过读取Python代码和库)?
发布于 2009-10-20 06:15:18
我猜,由于缺乏静态类型规则,解决方案只能是不精确的。
我不知道一些检查异常的工具,但你可以想出你自己的工具来满足你的需求(这是一个尝试静态分析的好机会)。
作为第一次尝试,您可以编写一个函数来构建一个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
",这对于快速的实际结果来说是很好的:)
发布于 2009-10-19 21:56:47
解决这个问题的正确工具是单元测试。如果你有由真实代码引发的异常,而单元测试没有引发,那么你需要更多的单元测试。
考虑一下这个
def f(duck):
try:
duck.quack()
except ??? could be anything
duck可以是任何对象
显然,如果鸭子没有叫声,你可以有一个AttributeError
,如果鸭子有叫声,你可以有一个TypeError
,但它是不可调用的。您不知道duck.quack()
可能会产生什么,甚至可能是DuckError
或其他什么
现在假设你有这样的代码
arr[i] = get_something_from_database()
如果它引发了一个IndexError
,你不知道它是来自arri还是来自数据库函数的内部。通常情况下,在哪里发生异常并不重要,而是发生了一些错误,没有发生您想要发生的事情。
一种方便的技术是捕获异常,也许还可以像下面这样重新处理异常
except Exception as e
#inspect e, decide what to do
raise
发布于 2009-12-12 08:02:32
到目前为止,没有人解释为什么你不能有一个完整的,100%正确的异常列表,所以我认为这是值得评论的。其中一个原因是函数是一流的。假设你有一个这样的函数:
def apl(f,arg):
return f(arg)
现在,apl
可以引发f
引发的任何异常。虽然在core库中没有太多类似的函数,但任何使用列表理解和自定义过滤器、map、reduce等的函数都会受到影响。
文档和源代码分析器是这里唯一“严肃”的信息来源。只要记住他们不能做的事情。
https://stackoverflow.com/questions/1591319
复制相似问题