1、错误和异常 原文参看: Errors and Exceptions
1.1 语法错误(Syntax Errors)
语法错误 也叫 解析错误
>>> while true
File "<stdin>", line 1
while true
^
SyntaxError: invalid syntax
>>>
1.2 异常 (Exception)
即使 语句 或者 表达式的语法是正确的 ,它在执行时仍然 可能造成 错误 。 在执行时 发现的 错误 叫做 异常。
1.3 处理异常
使用 try 语句处理异常 (一个 try 语句可以有多个 except从句 ,一个 except 从句 可以指定多个异常):
try:
#do something
except errorName:
#do something
执行流程:
★ 首先 try 从句 ( try 和 except 关键字 之间的语句)被执行
★ 如果 没有异常发生 , except 从句 将被跳过不执行,执行完 try 从句 后即完成。
★ 如果在执行 try 从句的过程中发生了异常 ,try从句未执行的部分将被跳过,然后 如果 except 关键字后指定的异常名称 和发生的异常相匹配 ,那么 except 从句将被执行 ,然后继续 执行 try 语句以后的代码
★ 如果发生的异常 和指定的异常不匹配 ,将会跳出 try 语句 ,如果没有发现相关的处理器 ,那么这就是一个未处理的异常,执行被迫终止并显示错误信息。
>>> while True:
... try:
... x=int(input("please enter a number:"))
... break
... except ValueError:
... print("that was not valid num,try again...")
...
please enter a number:e
that was not valid num,try again...
please enter a number:r
that was not valid num,try again...
please enter a number:3
>>>
exception.py
class B(Exception):
pass
class C(B):
pass
class D(C):
pass
for cls in [B, C, D]:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
cmd运行 python D:\workspace3\exception.py 后 输出 B C D
raise 语句 :
raise_stmt ::= "raise" [expression ["from" expression]]
如果没有表达式 , raise 语句 重新抛出当前 作用域 中仍然 活跃 的最后一个异常 ,如果在当前作用域 没有活跃的异常, RuntimeError 异常将被抛出 ,代表这是一个错误。
如果有表达式, raise 计算表达式 ,把 第一个产生的异常 作为异常对象 . 这个异常必须 是 BaseException 的 实例或者其子类。
>>> raise
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: No active exception to reraise
>>>
可选的 else 从句: 如果 try 从句 没有发生异常 ,则 else 从句 必须执行的代码 ,跟在 except 从句的后面
try:
#do something
except errorName:
#do something
else:
#do something
>>> try:
... print("try clause")
... except Exception:
... print("occure a ex")
... else:
... print("not find a ex")
...
try clause
not find a ex
>>> try:
... raise NameError
... except ValueError:
... print("value error")
... else:
... print("occure a ex")
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError
>>>
>>> try:
... raise Exception('xlch','man')
... except Exception as ex:
... print(ex.args)
... print(ex)
... print(type(ex))
...
('xlch', 'man')
('xlch', 'man')
<class 'Exception'>
>>>
1.4 引发异常(Raising Exception)
raise 语句允许 程序员 强制 指定一个异常。
>>> raise Exception("force a exception")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: force a exception
>>>
如果你只想知道 某个异常是否 发生 ,而不想去处理它 ,你可以在拦截后 再次 使用 raise 语句 引发这个异常
>>> try:
... raise Exception("force a exception")
... except Exception:
... print("force a exception..")
... raise
...
force a exception..
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
Exception: force a exception
>>>
1.5 自定义异常
自定义异常名称一般以 "Error" 结尾 ,和标准的 异常命名相似 。
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
1.6 定义清理动作
try 语句还有另外一个可选的从句 :在 结束 try 语句 之前总是会被执行的从句 ,使用 finally 关键字
>>> try:
... raise KeyboardInterrupt
... finally:
... print("goodbye")
...
goodbye
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
>>>
try:
#do something
except errorName as ex:
#发生指定异常时执行
except ...
.
.
else:
# try从句未发生异常且 try 从句执行结束后执行
finally:
#try 语句结束之前执行,总会被执行
当对象不再需要时 ,一些对象定义的标准的清理动作将被执行 ,不管使用该对象的操作是否成功 。
例如 打开一个文件处理完成后并没有关闭 ,而事实上 最好是关闭该文件 。 这时 可以使用 with 语句 打开文件 ,执行完毕后会对不需要的文件进行清理
处理文件后未关闭
for line in open("myfile.txt"):
print(line, end="")
文件处理后会被自动关闭
with open("myfile.txt") as f:
for line in f:
print(line, end="")