辨别Exception和Syntax Error
在写Python程序的时候常常会报错,报错通常有以下两种状况:
- 语法错误(Syntax Error): 局部语法错误属于异样
- 异样(Exception)
语法错误
语法错误也称为解析谬误,是最常遇到的一种谬误
In [1]: while True print('Hello!') File "<ipython-input-1-5c66e4fd0ae9>", line 1 while True print('Hello!') ^SyntaxError: invalid syntax
当代码不合乎Python语法的时候就会抛出SyntaxError。
异样
Python用异样对象来示意异常情况。遇到谬误后,会引发异样。如果异样没有解决或捕获,程序就会用traceback终止程序的执行,如果是在多线程程序中,则会终止以后线程的执行。
In [2]: 1/0---------------------------------------------------------------------------ZeroDivisionError Traceback (most recent call last)<ipython-input-2-05c9758a9c21> in <module>()----> 1 1/0ZeroDivisionError: division by zero
除以0时,就会抛出ZeroDivisionError异样(ZeroDivisionError类的一个实例)。
<!--more-->
异样层次结构
Python 3.5.2中内置异样的类层次结构如下:参考规范库
BaseException # 所有异样的基类 +-- SystemExit # 程序退出/终止 +-- KeyboardInterrupt # 由键盘中断(通常为Ctrl+C) 生成 +-- GeneratorExit # 由生成器.close()办法引发 +-- Exception # 所有非退出异样的基类 +-- StopIteration # 进行迭代谬误 +-- StopAsyncIteration # 进行异步迭代谬误 +-- ArithmeticError # 算数异样的基类 | +-- FloatingPointError # 浮点操作异样 | +-- OverflowError # 溢出导致的异样 | +-- ZeroDivisionError # 对0进行除或取模操作导致的异样 +-- AssertionError # 由assert语句引发 +-- AttributeError # 当属性名称有效时引发 +-- BufferError # 缓冲区谬误引发 +-- EOFError # 达到文件结尾时引发 +-- ImportError # import语句失败 +-- LookupError # 索引和键谬误 | +-- IndexError # 超出序列索引的范畴 | +-- KeyError # 键不存在 +-- MemoryError # 内存不足 +-- NameError # 无奈找到部分或全局名称 | +-- UnboundLocalError # 未绑定的局部变量 +-- OSError # 操作系统谬误 | +-- BlockingIOError # IO阻塞 | +-- ChildProcessError # 子过程 | +-- ConnectionError # 连贯谬误 | | +-- BrokenPipeError # 管道断开 | | +-- ConnectionAbortedError # 连贯停止 | | +-- ConnectionRefusedError # 连贯回绝 | | +-- ConnectionResetError # 连贯重置 | +-- FileExistsError # 文件已存在 | +-- FileNotFoundError # 文件不存在 | +-- InterruptedError # 中断谬误 | +-- IsADirectoryError # 目录谬误 | +-- NotADirectoryError # 非目录谬误 | +-- PermissionError # 权限谬误 | +-- ProcessLookupError # 过程查找谬误 | +-- TimeoutError # 超时谬误 +-- ReferenceError # 销毁被援用对象后依然应用援用 +-- RuntimeError # 运行时谬误 | +-- NotImplementedError # 没有实现的个性 | +-- RecursionError # 递归谬误 +-- SyntaxError # 语法错误 | +-- IndentationError # 缩进谬误 | +-- TabError # 应用不统一的制表符 +-- SystemError # 解释器中的非致命零碎谬误 +-- TypeError # 给操作传递了谬误的类型 +-- ValueError # 有效类型 | +-- UnicodeError # Unicode谬误 | +-- UnicodeDecodeError # Unicode解码谬误 | +-- UnicodeEncodeError # Unicode编码谬误 | +-- UnicodeTranslateError # Unicode转换谬误 +-- Warning # 正告的基类 +-- DeprecationWarning # 对于被弃用的特色的正告 +-- PendingDeprecationWarning # 对于个性将会被废除的正告 +-- RuntimeWarning # 可疑的运行时行为的正告 +-- SyntaxWarning # 可疑的语法的正告 +-- UserWarning # 用户代码生成的正告 +-- FutureWarning # 对于结构未来语义会有扭转的正告 +-- ImportWarning # import语句的正告 +-- UnicodeWarning # Unicode正告 +-- BytesWarning # Bytes正告 +-- ResourceWarning # 资源正告
- 所有异样的基类都是BaseException
- 除SystemExit,KeyboardInterrupt,GeneratorExit三种异样外都继承自Exception
捕捉异样
捕捉异样能够应用try/except语句。try/except语句用来检测try语句块中的谬误,从而让except语句捕捉异样信息并解决。
try/except
根底语法
try: <语句>except <name>: <语句> #如果在try局部引发了名为'name'的异样,则执行这段代码
示例
In [3]: try: ...: x = int(input("Please enter a number: ")) ...: except ValueError: ...: print("No valid number.") ...: Please enter a number: asdNo valid number.
多个except
In [4]: import sysIn [5]: try: ...: f = open('file.txt') # 文件不存在的时候就会抛出FileNotFoundError异样 ...: s = f.readline() ...: i = int(s.strip()) ...: except OSError: # FileNotFoundError异样的下层异样 ...: print('OS error.') ...: except ValueError: ...: print('Could not convert data to integer.') ...: except Exception: ...: print('Exception.') ...: except: # 不加具体异样类型时,会捕捉所有的异样,应该不必或者慎用 ...: print('Unexpected error:', sys.exc_info()[0]) ...: OS error.
各个except之间的执行程序:
- except程序捕捉try中抛出的异样
- 越具体的异样应该越靠前,越个别的异样应该越靠后
可选的else语句
语法
try: <语句>except <name>: <语句> #如果在try局部引发了名为'name'的异样,则执行这段代码else: <语句> #如果没有异样产生,则执行这段代码
如果try局部没有抛出异样,然而又必须执行的语句,则放在else语句中。
代码
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print('cannot open', arg) else: # 没有抛出异样(即文件正确关上)时打印出文件中的每一行 print(arg, 'has', len(f.readlines()), 'lines') f.close()
finally语句
finally语句用来定义在任何状况下都必须执行的语句。
In [1]: try: ...: raise KeyboardInterrupt ...: finally: ...: print('Goodbye') ...: Goodbye---------------------------------------------------------------------------KeyboardInterrupt Traceback (most recent call last)<ipython-input-8-132d568ca0fb> in <module>() 1 try:----> 2 raise KeyboardInterrupt 3 finally: 4 print('Goodbye') 5 KeyboardInterrupt:
带return语句的finally执行程序
def p(x): print(x) return xdef t(): try: return p(2) print('haha') finally: return p(3)x = t()# 输入后果为:23# 返回值x为3
可见,在try块中,只有有finally语句,即便函数提前返回,也会在退出try块之前执行finally语句,因而返回值会被finally中的return语句代替。
综合应用示例
In [1]: def divide(x, y): ...: try: ...: result = x / y ...: except ZeroDivisionError: ...: print('division by zero!') ...: else: ...: print('result is ', result) ...: finally: ...: print('executing finally clause.') ...: In [2]: divide(2, 0)division by zero!executing finally clause.In [3]: divide(2, 1)result is 2.0executing finally clause.In [4]: divide('2', '1')executing finally clause.---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-4-34bb38fa74fd> in <module>()----> 1 divide('2', '1')<ipython-input-1-4273ffa41b76> in divide(x, y) 1 def divide(x, y): 2 try:----> 3 result = x / y 4 except ZeroDivisionError: 5 print('division by zero!')TypeError: unsupported operand type(s) for /: 'str' and 'str'
论断:
- 任何状况下finally语句都会执行。
- 即便try局部中有return语句,也会在退出try块之前执行finally语句,并且返回值是finally中的return
- 如果有异样没有被解决,则在执行实现finally语句之后会会抛出没有被解决的异样
- 在理论应用中,finally通常用来开释额定的资源,比方文件或者网络连接
被动抛出异样
raise语句
In [1]: raise NameError('Hello')---------------------------------------------------------------------------NameError Traceback (most recent call last)<ipython-input-1-64f372e60821> in <module>()----> 1 raise NameError('Hello')NameError: Hello
用户自定义异样
用户自定义异样类时,应该间接或者间接的继承自Exception类。
class CustomException(Exception): def __init__(self, code, message): self.code = code self.message = messagetry: raise CustomException(500, 'error')except CustomException as e: print('{},{}'.format(e.code, e.message))# 输入后果:500,error
异样的传递
在函数内引发异样时,如果异样没有被捕捉到,那么它就会被流传到函数被调用的中央。
In [1]: def a(): ...: raise Exception('Hello') ...: In [2]: def b(): ...: print('enter b') ...: a() # 函数a中引发的异样,会传递到父函数的调用出 ...: print('exit b') # a中抛出异样之后传递到b,停止b的执行 ...: In [3]: b()enter b---------------------------------------------------------------------------Exception Traceback (most recent call last)<ipython-input-3-9c619ddbd09b> in <module>()----> 1 b()<ipython-input-2-f99a565bd6f8> in b() 1 def b(): 2 print('enter b')----> 3 a() 4 print('exit b') 5 <ipython-input-1-6e68e60e93b5> in a() 1 def a():----> 2 raise Exception('Hello')Exception: Hello
记得帮我点赞哦!
精心整顿了计算机各个方向的从入门、进阶、实战的视频课程和电子书,依照目录正当分类,总能找到你须要的学习材料,还在等什么?快去关注下载吧!!!
朝思暮想,必有回响,小伙伴们帮我点个赞吧,非常感谢。
我是职场亮哥,YY高级软件工程师、四年工作教训,回绝咸鱼争当龙头的斜杠程序员。听我说,提高多,程序人生一把梭
如果有幸能帮到你,请帮我点个【赞】,给个关注,如果能顺带评论给个激励,将不胜感激。
职场亮哥文章列表:更多文章
自己所有文章、答复都与版权保护平台有单干,著作权归职场亮哥所有,未经受权,转载必究!