Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:我如何知道方法调用可能引发哪些异常_Python_Exception - Fatal编程技术网

Python:我如何知道方法调用可能引发哪些异常

Python:我如何知道方法调用可能引发哪些异常,python,exception,Python,Exception,有没有办法知道(在编码时)在执行python代码时会出现哪些异常? 由于我不知道可能抛出哪种异常类型(并且不要告诉我阅读文档。很多时候,异常可以从深层传播。很多时候,文档没有更新或正确),我90%的时间都会捕获基本异常类。有什么工具可以检查这个吗?(比如通过阅读python代码和libs)?您应该只捕获要处理的异常 通过具体类型捕捉所有异常是毫无意义的。您应该捕获您可以并将要处理的特定异常。对于其他异常,您可以编写一个泛型catch来捕获“基本异常”,记录它(使用str()函数)并终止您的程序(

有没有办法知道(在编码时)在执行python代码时会出现哪些异常?
由于我不知道可能抛出哪种异常类型(并且不要告诉我阅读文档。很多时候,异常可以从深层传播。很多时候,文档没有更新或正确),我90%的时间都会捕获基本异常类。有什么工具可以检查这个吗?(比如通过阅读python代码和libs)?

您应该只捕获要处理的异常

通过具体类型捕捉所有异常是毫无意义的。您应该捕获您可以并将要处理的特定异常。对于其他异常,您可以编写一个泛型catch来捕获“基本异常”,记录它(使用
str()
函数)并终止您的程序(或者在紧急情况下执行其他适当的操作)

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

您可能也感兴趣,而不是您正在使用的库的参考

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


无论如何,您都必须运行测试,因为即使存在通过源代码获取异常的方法,它也不会让您知道应该如何处理这些异常。当您捕获
索引器时,可能应该显示错误消息“未找到文件needful.txt!”?只有测试才能判断。

通常,您只需要捕获大约几行代码的异常。您不希望将整个
main
函数放入
try except
子句中。对于每几行,您现在应该总是(或者能够轻松地检查)会引发什么样的异常

文档有详尽的描述。不要试图排除那些您不期望的异常,它们可能在调用代码中得到处理/期望

编辑:可能抛出的内容显然取决于您正在做什么!访问序列的随机元素:
索引器
,dict的随机元素:
键错误
,等等


只要试着在空闲状态下运行这几行代码,就会引起异常。当然,单元测试是一个更好的解决方案。

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

想想这个

def f(duck):
    try:
        duck.quack()
    except ??? could be anything
鸭子可以是任何物体

显然,如果duck没有江湖郎中,您可以有一个
AttributeError
,如果duck有江湖郎中但不能调用,您可以有一个
TypeError
。你不知道duck.quack()
可能会引发什么,甚至可能是一个
DuckError
之类的问题

现在假设你有这样的代码

arr[i] = get_something_from_database()
except Exception as e
    #inspect e, decide what to do
    raise
如果它引发一个
索引器
,您不知道它是来自arr[i]还是来自数据库函数的深层。通常情况下,异常发生在何处并不重要,而是发生了一些错误,您希望发生的事情没有发生

一种简便的方法是捕获并可能像这样重新释放异常

arr[i] = get_something_from_database()
except Exception as e
    #inspect e, decide what to do
    raise

我猜解决方案可能只是因为缺少静态类型规则而不精确

我不知道有什么工具可以检查异常,但是你可以找到自己的工具来满足你的需要(这是一个很好的机会来进行静态分析)

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

x
成为以下程序:

x = '''\
if f(x):
    raise IOError(errno.ENOENT, 'not found')
else:
    e = g(x)
    raise e
'''
使用
编译器
包构建AST:

tree = compiler.parse(x)
然后定义一个
Raise
visitor类:

class RaiseVisitor(object):
    def __init__(self):
        self.nodes = []
    def visitRaise(self, n):
        self.nodes.append(n)
然后走到AST收集
提升
节点:

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
”,这对于快速的实际结果来说是很好的:)

我在使用套接字时遇到了这个问题,我想找出我将遇到的所有错误条件(因此,我不想试图创建错误,也不想弄清楚socket是什么,我只是想要一个简明的列表)。最终,我将“/usr/lib64/python2.4/test/test_socket.py”改为“raise”:


这是一个相当简洁的错误列表。当然,这只适用于具体情况,取决于测试是否准确(通常是这样)。否则,您几乎需要捕获所有异常,记录它们,分析它们,并找出如何处理它们(使用单元测试并不困难)。

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

def apl(f,arg):
   return f(arg)
现在
apl
可以引发
f
引发的任何异常。虽然核心库中没有很多这样的函数,但是任何使用列表理解和自定义过滤器、映射、减少等的功能都会受到影响


文件和源分析仪是此处唯一的“严重”信息来源。记住他们不能做的事情。

我发现有两种方法可以提供信息。第一个,在iPython中运行代码
try:
   so something
except Exception as err:
   print "Some message"
   print err.__class__
   print err
   exit(1)