"提高"在一个python函数的末尾"尝试"或"除了"块

时间:2014-09-02 20:51:12

标签: python python-2.7

raise做什么,如果它不在tryexcept子句中,而只是作为函数中的最后一个语句?

def foo(self):
    try:
        # some code that raises an exception
    except Exception as e:
        pass

    # notice that the "raise" is outside
    raise

此示例打印1但不打印2,因此必须是最后一个raise语句只会引发最后抛出的异常。

def foo():
    try:
        raise Exception()
    except Exception as e:
        pass

    print 1
    raise
    print 2

if __name__ == '__main__':
    foo()

此类使用模式的任何官方文档?

5 个答案:

答案 0 :(得分:3)

正如Russell所说,

  

raise语句重新引发最后一次捕获的异常。

这是否发生在try-except块中并不重要。如果存在已捕获的异常,则调用raise将重新引发该异常。否则,Python会抱怨先前捕获的异常为None并引发TypeError,因为None不是实际可以引发的内容。

正如tdelaney所说,除了错误处理功能之外,这样做似乎没有意义。我个人认为它甚至不属于错误处理函数,因为raise仍然应该在except子句中。无论是否发生错误,都可以使用它来尝试执行代码,但是finally子句是正确的方法。另一种可能性是使用它作为确定执行函数时是否发生错误的方法,但有更好的方法可以做到这一点(例如返回一个额外的值来指示错误是否发生在哪里)。

答案 1 :(得分:1)

raise语句重新引发最后捕获的异常。 https://docs.python.org/2/tutorial/errors.html#raising-exceptions

答案 2 :(得分:1)

documentation我们可以看到:

  

如果没有表达式,则raise重新引发最后一个异常   在当前范围内活跃。如果没有活动的例外   当前范围,引发TypeError异常,表明这是   错误(如果在IDLE下运行,则引发Queue.Empty异常   代替)。

这意味着,对于代码,如果try ... except块中没有发生异常,那么您将强制程序引发TypeError异常。

答案 3 :(得分:1)

裸露加注再次引发当前例外。除非在异常中调用函数,否则这通常在函数末尾没有意义:

本身,加注无效,python抛出自己的异常

>>> def x():
...     raise
>>> x()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in x
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType

但是如果在异常块中调用它,它会很明智地运行

>>> try:
...     int('a')
... except:
...     x()
... 
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File "<stdin>", line 2, in <module>
ValueError: invalid literal for int() with base 10: 'a'
>>> 

修改

如果函数尝试某种恢复,这可能是一个非常合理的事情。该功能可以修复损坏的内容,记录消息,触发灭火器等......如果它仍然认为系统出错,可以raise

答案 4 :(得分:0)

我遇到这样的问题,如果我的函数未返回值,则需要在try / except块之外引发以前捕获的异常。我在systraceback模块中进行了一些浏览,但是找不到一个好的方法来执行此操作,因此我最终将异常存储在了块外。

def foo():
    caught = None

    try:
        raise Exception
    except Exception as e:
        caught = e
        pass

    raise caught


f = foo()

输出

Traceback (most recent call last):
  line 13, in <module>
  line 10, in foo
  line 5, in foo
Exception

很显然,这在上面的示例中没有用,但是如果您需要在循环中尝试几次并重新举起,则非常有用。我的特定需要是HTTP请求重试机制。

import time

def foo(key):
    caught = None
    
    for i in [1, 2, 3, 4, 5]:
        try:
            return d[key]
        except KeyError as e:
            caught = e
            print(i)
            time.sleep(i)
            continue

    raise caught

d = {"bar": "baz"}

f = foo(key="baz")

输出

1
2
3
4
5
Traceback (most recent call last):
  line 19, in <module>
  line 15, in foo
  line 8, in foo
KeyError: 'baz'