python异常小记

本文介绍了Python中的异常处理机制,包括如何通过`try`、`except`、`raise`语句来管理和处理异常。异常是程序运行时错误的表示,Python解释器在遇到运行时错误时会抛出异常。`try`块用于包裹可能引发异常的代码,`except`用来捕获并处理特定类型的异常。`raise`语句可以显式地引发异常,而没有`expression`的`raise`将重新抛出最近的异常。异常可以通过类实例进行标识,并且可以使用`with_traceback()`设置自定义的追踪信息。`except`子句可以使用`as`关键字获取异常实例。`finally`子句用于清理代码,无论是否发生异常都会执行。异常链可以通过`from`子句实现,允许一个异常引用导致它的另一个异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.3. Exceptions

Exceptions are a means of breaking out of the normal flow of control of a code block in order to handle errors or other exceptional

异常是为了处理错误和其他异常情况的一种手段

 conditions. An exception is raised at the point where the error is detected; it may be handled by the surrounding code block or by any code block that directly or indirectly invoked the code block where the error occurred.

The Python interpreter raises an exception when it detects a run-time error (such as division by zero). A Python program can also explicitly raise an exception with the raise statement. Exception handlers are specified with the try ... except statement. The finally clause of such a statement can be used to specify cleanup code which does not handle the exception, but is executed whether an exception occurred or not in the preceding code.

异常的产生

1.python解释器检测到运行时错误时会产生一个异常

2.也可以使用raise语句显示引发一个异常

异常处理程序

1.由try语句指定

Python uses the “termination” model of error handling: an exception handler can find out what happened and continue execution at an outer level, but it cannot repair the cause of the error and retry the failing operation (except by re-entering the offending piece of code from the top).

When an exception is not handled at all, the interpreter terminates execution of the program, or returns to its interactive main loop. In either case, it prints a stack backtrace, except when the exception is SystemExit.

当异常没有被处理

1.解释器会终止程序的执行

2.返回到解释器的交互主循环

Exceptions are identified by class instances. The except clause is selected depending on the class of the instance: it must reference the class of the instance or a base class thereof. The instance can be received by the handler and can carry additional information about the exceptional condition.

异常由类的实例标识,except子句的选择依赖于类的实例: 必须引用实例的类或该类的基类.

实例可以被处理程序接收,并且可以携带关于异常的附加信息

Note

 

Exception messages are not part of the Python API. Their contents may change from one version of Python to the next without warning and should not be relied on by code which will run under multiple versions of the interpreter.

7.8. The raise statement

raise_stmt ::=  "raise" [expression ["from" expression]]

If no expressions are present, raise re-raises the last exception that was active in the current scope. If no exception is active in the current scope, a RuntimeError exception is raised indicating that this is an error.

如果raise后没有expression,会重新引发当前范围内最后激发的异常.如果当前范围没有异常被激活,会产生一个运行时错误异常以表明这是一个错误

Otherwise, raise evaluates the first expression as the exception object. It must be either a subclass or an instance of BaseException. If it is a class, the exception instance will be obtained when needed by instantiating the class with no arguments.

另一方面,raise评估第一个表达式作为异常对象,该表达式必须是BaseException的子类或者实例.如果是一个类,可以通过实例化该类获得异常实例对象

The type of the exception is the exception instance’s class, the value is the instance itself.

异常的类型是异常的类类型,异常的值是异常实例对象本身

A traceback object is normally created automatically when an exception is raised and attached to it as the __traceback__ attribute,

当引发异常时会自动创建一个traceback对象(代表异常的堆栈跟踪),并且以__traceback__属性的形式附加到该异常实例对象

which is writable. You can create an exception and set your own traceback in one step using the with_traceback() exception 

该属性可写,可以使用with_traceback()异常函数设置异常的traceback

method (which returns the same exception instance, with its traceback set to its argument), like so:

返回值是设置traceback到其参数的同一个异常实例对象

raise Exception("foo occurred").with_traceback(tracebackobj)

The from clause is used for exception chaining: if given, the second expression must be another exception class or instance, 

from子句用于异常链接: 第二个参数必须是另一个异常类或异常实例对象

which will then be attached to the raised exception as the __cause__ attribute (which is writable). If the raised exception is not handled, both exceptions will be printed:

被链接的异常会以__cause__属性的形式附加到当前异常实例对象,如果raise出的异常没有处理,当前异常和链接的异常都会被打印

>>>
>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

A similar mechanism works implicitly if an exception is raised inside an exception handler or a finally clause: the previous 

exception is then attached as the new exception’s __context__ attribute:

在异常处理程序或在finally子句中产生的异常有一个和from相似的隐式机制: 前一个异常会以__context__属性的形式附加到新的异常实例对象

>>>
>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Additional information on exceptions can be found in section Exceptions, and information about handling exceptions is in section The try statement.

8.4. The try statement

The try statement specifies exception handlers and/or cleanup code for a group of statements:

try语句指定异常处理程序,和/或一组语句的代码

try_stmt  ::=  try1_stmt | try2_stmt
try1_stmt ::=  "try" ":" suite
               ("except" [expression ["as" identifier]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]
try2_stmt ::=  "try" ":" suite
               "finally" ":" suite

The except clause(s) specify one or more exception handlers. When no exception occurs in the try clause, no exception handler

except子句指定一个或多个异常处理程序.如果try子句中没有异常发生,没有异常处理程序被执行

is executed. When an exception occurs in the trysuite, a search for an exception handler is started. This search inspects the

当try套件中出现一个异常,就会启动搜索异常处理程序

except clauses in turn until one is found that matches the exception. An expression-less except clause, if present, must be last; it

该搜索依次检查每一个except子句,知道找到匹配该exception子句的except子句.匹配任何异常的except子句必须在最后

matches any exception. For an except clause with an expression, that expression is evaluated, and the clause matches the

exception if the resulting object is “compatible” with the exception.

带有表达式的except子句,表达式会被评估,如果结果对象和该异常兼容那么会匹配该except子句.

An object is compatible with an exception if it is the class or a base class of the exception object or a tuple containing an item compatible with the exception.

一个对象和一个异常兼容,如果该对象是异常对象类或基类,或者包含兼容该异常的项目的元组

If no except clause matches the exception, the search for an exception handler continues in the surrounding code and on the invocation stack. [1]

 [1](
The exception is propagated to the invocation stack unless there is a finally clause which happens to raise another exception. That new exception causes the old one to be lost.
异常会传播到调用堆栈,除非在finally子句中产生新的异常,新的异常会导致旧的异常消失
)

如果没有except子句和该异常匹配,对异常处理程序的搜索会继续在包围代码块和调用堆栈中搜索

If the evaluation of an expression in the header of an except clause raises an exception, the original search for a handler is canceled and a search starts for the new exception in the surrounding code and on the call stack (it is treated as if the entire try statement raised the exception).

如果评估except子句中的表达式引发一个异常,原来对异常处理程序的搜索将会被取消,并开始在围绕代码和调用堆栈中搜索新异常的搜索(该异常当做是整个try语句产生的异常)

When a matching except clause is found, the exception is assigned to the target specified after the as keyword in that except 

当搜索到匹配的except子句,异常会被赋值给as后的目标参数,并且该except子句套件会被执行

clause, if present, and the except clause’s suite is executed. All except clauses must have an executable block. When the end of 

所有的except子句必须有一个可执行代码块,当执行到该代码块的结尾,

this block is reached, execution continues normally after the entire try statement. (This means that if two nested handlers exist for

会继续执行tyr之后的语句(这意味着,处理同一个异常的异常处理程序存在嵌套关系的话,如果内层异常处理程序处理了该异常,那么外层异常处理程序,不会再执行)

the same exception, and the exception occurs in the try clause of the inner handler, the outer handler will not handle the exception.)

When an exception has been assigned using as target, it is cleared at the end of the except clause. This is as if

赋值给as后target参数的异常会在该except子句执行结束时被清除

except E as N:
    foo

was translated to

except E as N:
    try:
        foo
    finally:
        del N

This means the exception must be assigned to a different name to be able to refer to it after the except clause. 

者意味着,异常必须赋值给不同名称,保证except子句结束后可以访问


Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs.

异常会被清除,因为异常实例附加有traceback(traceback object以__traceback__属性的形式附加到异常实例对象),这会形成堆栈框架上的循环引用,保持堆栈框架中的所有局部变量生存,知道下一次垃圾回收出现

Before an except clause’s suite is executed, details about the exception are stored in the sys module and can be accessed

except子句套件执行前,异常的详细信息保存在sys模块中,可以通过sys.exc_info()函数访问

via sys.exc_info()sys.exc_info() returns a 3-tuple consisting of the exception class, the exception instance and a traceback

sys.exc_info()函数返回一个由异常实例对象对应的类, 异常实例对象, 和traceback object构成的元组,标识程序中异常的发生点

object (see section The standard type hierarchy) identifying the point in the program where the exception occurred. sys.exc_info() values are restored to their previous values (before the call) when returning from a function that handled an exception.

当从处理异常的函数中返回,sys.exc_info()的值会恢复到之前的值(被调用之前)

The optional else clause is executed if and when control flows off the end of the try clause. [2] Exceptions in the else clause are not handled by the preceding except clauses.

 [2](
Currently, control “flows off the end” except in the case of an exception or the execution of a returncontinue,
or break statement.
)

If finally is present, it specifies a ‘cleanup’ handler. The try clause is executed, including any except and else clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. If

try, except, else,子句中的异常如果没有被处理,会被暂时保存.在执行finally子句时,如果存在暂存的异常,会在finally子句的结尾被重新引发.如果finally子句引发新的异常,原来暂存的异常会以__context__属性的形式附加到该异常实例对象.如果finally

there is a saved exception it is re-raised at the end of the finally clause. If the finally clause raises another exception, the saved exception is set as the context of the new exception. If the finally clause executes a return or break statement, the saved exception is discarded:

>>>
>>> def f():
...     try:
...         1/0
...     finally:
...         return 42
...
>>> f()
42

The exception information is not available to the program during execution of the finally clause.

When a returnbreak or continue statement is executed in the try suite of a try...finally statement, the finally clause is also executed ‘on the way out.’ A continue statement is illegal in the finally clause. (The reason is a problem with the current implementation — this restriction may be lifted in the future).

The return value of a function is determined by the last return statement executed. Since the finally clause always executes, a return statement executed in the finally clause will always be the last one executed:

>>>
>>> def foo():
...     try:
...         return 'try'
...     finally:
...         return 'finally'
...
>>> foo()
'finally'

Additional information on exceptions can be found in section Exceptions, and information on using the raise statement to generate exceptions may be found in section The raise statement.









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值