#对独占一行的所有变量或语句都自动显示
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = ‘all’
错误与异常
print(1/0)
ZeroDivisionError Traceback (most recent call last)
in ()
----> 1 print(1/0)
ZeroDivisionError: division by zero
#对独占一行的所有变量或语句都自动显示
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = ‘all’
‘123’+456#对独占一行的所有变量或语句都自动显示
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = ‘all’
TypeError Traceback (most recent call last)
in ()
----> 1 ‘123’+456
TypeError: must be str, not int
#程序的错误 语法错误(编译错误),逻辑错误和运行时错误
什么是异常?
异常指的是程序在没有语法错误的前提下,在运行期间产生的特定错误。
每个特定错误都对应一个异常类对象。当产生某个特定错误时,其对应的异常类对象的实例对象就会被抛出。如果在程序中对抛出的异常实例对象不进行捕获和处理,程序就会停止运行,并且打印错误的详细信息,包括:
1.Traceback,它指的是异常调用的跟踪信息,其中列出了程序中的相关行数;
2.对应的异常类对象的名称,以及异常的错误信息。
如果在程序中对抛出的异常实例对象进行捕获和处理,程序就会继续运行。
内置异常类对象和自定义的异常类对象对应的错误会被看做异常。
对于每个异常类对象所表示的特定错误,可以参考官方文档:
https://docs.python.org/3/library/exceptions.html
所有内置异常类对象的基类是Exception。
dir(builtins)
[‘ArithmeticError’,
‘AssertionError’,
‘AttributeError’,
‘BaseException’,
‘BlockingIOError’,
‘BrokenPipeError’,
‘BufferError’,
‘BytesWarning’,
‘ChildProcessError’,
‘ConnectionAbortedError’,
‘ConnectionError’,
‘ConnectionRefusedError’,
‘ConnectionResetError’,
‘DeprecationWarning’,
‘EOFError’,
‘Ellipsis’,
‘EnvironmentError’,
‘Exception’,
‘False’,
‘FileExistsError’,
‘FileNotFoundError’,
‘FloatingPointError’,
‘FutureWarning’,
‘GeneratorExit’,
‘IOError’,
‘ImportError’,
‘ImportWarning’,
‘IndentationError’,
‘IndexError’,
‘InterruptedError’,
‘IsADirectoryError’,
‘KeyError’,
‘KeyboardInterrupt’,
‘LookupError’,
‘MemoryError’,
‘ModuleNotFoundError’,
‘NameError’,
‘None’,
‘NotADirectoryError’,
‘NotImplemented’,
‘NotImplementedError’,
‘OSError’,
‘OverflowError’,
‘PendingDeprecationWarning’,
‘PermissionError’,
‘ProcessLookupError’,
‘RecursionError’,
‘ReferenceError’,
‘ResourceWarning’,
‘RuntimeError’,
‘RuntimeWarning’,
‘StopAsyncIteration’,
‘StopIteration’,
‘SyntaxError’,
‘SyntaxWarning’,
‘SystemError’,
‘SystemExit’,
‘TabError’,
‘TimeoutError’,
‘True’,
‘TypeError’,
‘UnboundLocalError’,
‘UnicodeDecodeError’,
‘UnicodeEncodeError’,
‘UnicodeError’,
‘UnicodeTranslateError’,
‘UnicodeWarning’,
‘UserWarning’,
‘ValueError’,
‘Warning’,
‘WindowsError’,
‘ZeroDivisionError’,
‘IPYTHON’,
‘build_class’,
‘debug’,
‘doc’,
‘import’,
‘loader’,
‘name’,
‘package’,
‘spec’,
‘abs’,
‘all’,
‘any’,
‘ascii’,
‘bin’,
‘bool’,
‘bytearray’,
‘bytes’,
‘callable’,
‘chr’,
‘classmethod’,
‘compile’,
‘complex’,
‘copyright’,
‘credits’,
‘delattr’,
‘dict’,
‘dir’,
‘display’,
‘divmod’,
‘enumerate’,
‘eval’,
‘exec’,
‘filter’,
‘float’,
‘format’,
‘frozenset’,
‘get_ipython’,
‘getattr’,
‘globals’,
‘hasattr’,
‘hash’,
‘help’,
‘hex’,
‘id’,
‘input’,
‘int’,
‘isinstance’,
‘issubclass’,
‘iter’,
‘len’,
‘license’,
‘list’,
‘locals’,
‘map’,
‘max’,
‘memoryview’,
‘min’,
‘next’,
‘object’,
‘oct’,
‘open’,
‘ord’,
‘pow’,
‘print’,
‘property’,
‘range’,
‘repr’,
‘reversed’,
‘round’,
‘set’,
‘setattr’,
‘slice’,
‘sorted’,
‘staticmethod’,
‘str’,
‘sum’,
‘super’,
‘tuple’,
‘type’,
‘vars’,
‘zip’]
异常处理
try…except…else…finally结构
程序在运行期间产生异常时,为了让程序能够继续执行,可以对抛出的异常实例对象进行捕获和处理,这是通过try-except语句实现的:把可能会产生异常的代码放在try语句块中以捕获异常实例对象,把处理异常的代码放在由若干个except子句组成的except语句块中。
try-except语句的语法格式为:
try:
可能会产生异常的代码
except 异常类对象1:
当前except子句处理异常的代码
except 异常类对象2:
当前except子句处理异常的代码
…
except 异常类对象n:
当前except子句处理异常的代码
try:
result = 1/0
print(result)
except:
print(“打错了!”)
打错了!
result = 1/0
print(result)
ZeroDivisionError Traceback (most recent call last)
in ()
----> 1 result = 1/0
2 print(result)
ZeroDivisionError: division by zero
try:
result = 1/0
print(result)
except ZeroDivisionError :
print(“0不能作为除数”)
0不能作为除数
try:
result = 1/0
print(result)
except TypeError :
print(“0不能作为除数”)
ZeroDivisionError Traceback (most recent call last)
in ()
1 try:
----> 2 result = 1/0
3 print(result)
4 except TypeError :
5 print(“0不能作为除数”)
ZeroDivisionError: division by zero
为了在except语句块中将所有的异常类对象尽可能地覆盖到,可以将最后一个except子句中的异常类对象指定为Exception(内置的异常类对象和自定义类对象都继承自Exception),或者在最后一个except子句中不指定异常类对象。
try:
result = int(‘abc’)
print(result)
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
ValueError Traceback (most recent call last)
in ()
1 try:
----> 2 result = int(‘abc’)
3 print(result)
4 except ImportError :
5 print(“导入错误”)
ValueError: invalid literal for int() with base 10: ‘abc’
result = int(‘abc’)
print(result)
ValueError Traceback (most recent call last)
in ()
----> 1 result = int(‘abc’)
2 print(result)
ValueError: invalid literal for int() with base 10: ‘abc’
try:
result = int(‘abc’)
print(result)
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
except:
print(“未知错误!”)
未知错误!
如果抛出的异常实例对象所对应的类对象是except子句中异常类对象的子类,那么该except子句也会被匹配。
try:
result = 1/0
print(result)
except ArithmeticError :
print(“数学错误”)
数学错误
try:
result = 1/0
print(result)
except ArithmeticError :
print(“数学错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
数学错误
try:
result = 1/0
print(result)
except ZeroDivisionError :
print(“0不能作为除数”)
except ArithmeticError :
print(“数学错误”)
0不能作为除数
#看先后的顺序
当多个异常类对象对应的异常处理代码完全相同时,可以把这些异常类对象以元组的形式放在一个except子句中。
try:
result = 1/0
print(result)
except TypeError :
print(“运行出错了”)
except ZeroDivisionError :
print(“运行出错了”)
except ValueError :
print(“运行出错了”)
运行出错了
try:
result = 1/0
print(result)
except (TypeError,ZeroDivisionError,ValueError) :
print(“运行出错了”)
运行出错了
如果想在匹配到的except子句中访问异常实例对象,可以在except子句中的冒号前添加关键字as和一个变量。
try:
result = 1/0
print(result)
except ZeroDivisionError as err :
print(type(err))
print(err)
<class ‘ZeroDivisionError’>
division by zero
try…except…else
可以在while语句或for-in语句的后面添加eLse从句,这样,如果没有执行循环体中的break语句从而提前退出循环,就会执行else从句。
类似地,可以在try-except语句的后面添加else从句,其语法格式为:
try:
可能会产生异常的代码
except 异常类对象1:
当前except子句处理异常的代码
except 异常类对象2:
当前except子句处理异常的代码
…
except 异常类对象n:
当前except子句处理异常的代码
else:
try语句块中没有产生异常时执行的代码
try:
result = 1/0
print(result)
except (TypeError,ValueError):
print(“类型错误或值错误”)
#except
except Exception:
print(“其他错误”)
其他错误
while True:
try:
x = int(input(‘请输入一个整数:’))
except ValueError:
print(‘无效的输入,请再次输入’)
else:
print(‘输入的整数为:’,x)
break
请输入一个整数:a
无效的输入,请再次输入
请输入一个整数:b
无效的输入,请再次输入
请输入一个整数:c
无效的输入,请再次输入
请输入一个整数:d
无效的输入,请再次输入
请输入一个整数:6
输入的整数为: 6
try…except…finally
可以在try-except语句的后面添加finally从句,其语法格式为:
try:
可能会产生异常的代码
except 异常类对象1:
当前except子句处理异常的代码
except 异常类对象2:
当前except子句处理异常的代码
…
except 异常类对象n:
当前except子句处理异常的代码
else:
总会被执行的代码
因为finally从句总会被执行,所以通常在finally从句中释放资源,例如:关闭文件,关闭网络连接等。
try:
result = 1/2
print(result)
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
finally:
print(“释放资源”)
print(“结束”)
0.5
释放资源
结束
try:
result = 1/0
print(result)
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
finally:
print(“释放资源”)
print(“结束”)
0不能作为除数
释放资源
结束
try:
result = int(‘abc’)
print(result)
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
finally:
print(“释放资源”)
print(“结束”)
释放资源
ValueError Traceback (most recent call last)
in ()
1 try:
----> 2 result = int(‘abc’)
3 print(result)
4 except ImportError :
5 print(“导入错误”)
ValueError: invalid literal for int() with base 10: ‘abc’
try…except…else…finally…
try:
result = 1/2
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
else:
print(result)
finally:
print(“释放资源”)
print(“结束”)
0.5
释放资源
结束
try:
result = 1/0
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
else:
print(result)
finally:
print(“释放资源”)
print(“结束”)
0不能作为除数
释放资源
结束
try:
result = int(‘abc’)
except ImportError :
print(“导入错误”)
except ZeroDivisionError :
print(“0不能作为除数”)
except TypeError :
print(“类型错误”)
else:
print(result)
finally:
print(“释放资源”)
print(“结束”)
释放资源
ValueError Traceback (most recent call last)
in ()
1 try:
----> 2 result = int(‘abc’)
3 except ImportError :
4 print(“导入错误”)
5 except ZeroDivisionError :
ValueError: invalid literal for int() with base 10: ‘abc’
对于前面课程中的示例,在发生异常时的异常实例对象都是被自动抛出的。
我们可以使用raise语句手动抛出异常实例对象,其语法格式为:
raise 异常类对象[([参数])]
如果没有传入参数,可以省略掉小括号。
raise ZeroDivisionError(‘0不能作为除数’)
ZeroDivisionError Traceback (most recent call last)
in ()
----> 1 raise ZeroDivisionError(‘0不能作为除数’)
ZeroDivisionError: 0不能作为除数
raise ZeroDivisionError() #无参数时,小括号可以省略
ZeroDivisionError Traceback (most recent call last)
in ()
----> 1 raise ZeroDivisionError() #无参数时,小括号可以省略
ZeroDivisionError:
如果在except语句块中不想对异常实例对象进行处理,可以使用关键字raise将其原样抛出。
raise Warning(“大胆小贼!”)
Warning Traceback (most recent call last)
in ()
----> 1 raise Warning(“大胆小贼!”)
Warning: 大胆小贼!
如果在except语句块中不想对异常实例对象进行处理,还可以使用raise语句手动抛出另外一个异常类对象的实例对象。
try:
raise ZeroDivisionError(‘0不能作为除数’)
except ZeroDivisionError:
raise ValueError(‘输入错误’)
ZeroDivisionError Traceback (most recent call last)
in ()
1 try:
----> 2 raise ZeroDivisionError(‘0不能作为除数’)
3 except ZeroDivisionError:
ZeroDivisionError: 0不能作为除数
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
in ()
2 raise ZeroDivisionError(‘0不能作为除数’)
3 except ZeroDivisionError:
----> 4 raise ValueError(‘输入错误’)
ValueError: 输入错误
自定义异常
尽管Python内的异常类对象可以满足我们绝大部分的需求,但是有时候我们可能想要创建自定义的异常类对象。
正如所有内置异常类对象的基类是Exception,自定义异常类对象只需要继承Exception或其子类。
class MyException(Exception):
pass
raise MyException
MyException Traceback (most recent call last)
in ()
1 class MyException(Exception):
2 pass
----> 3 raise MyException
MyException:
当函数内发生异常时,异常实例对象会被抛给该函数的调用者,如果该函数的调用者没有捕获和处理,则继续抛给上一层的调用者,这样一直向上抛,最后会被Python解释器捕获。
def f1():
print(1/0)
def f2():
f1()
def f3():
f2()
f3()
ZeroDivisionError Traceback (most recent call last)
in ()
5 def f3():
6 f2()
----> 7 f3()
in f3()
4 f1()
5 def f3():
----> 6 f2()
7 f3()
in f2()
2 print(1/0)
3 def f2():
----> 4 f1()
5 def f3():
6 f2()
in f1()
1 def f1():
----> 2 print(1/0)
3 def f2():
4 f1()
5 def f3():
ZeroDivisionError: division by zero
当异常实例对象被向上抛的过程中,可以选择在合适的层对异常实例对象进行捕获和处理,而不需要在每一次进行捕获和处理。
def f1():
print(1/0)
def f2():
f1()
def f3():
try:
f2()
except ZeroDivisionError as err:
print(err)
f3()
division by zero
import random
random.randint(0,5)
1
s = [3,8,5,2]
s.sort()
print(s)
[2, 3, 5, 8]
s = s.sort()
print(s)
None
sorted([1,2,3],reverse = True) == reversed([1,2,3])
False