python异常处理

一、异常和错误

python中有两种错误:
1、语法错误(过不了解释器的语法检测,必须在程序执行前改正。)
2、 逻辑错误,解释器的语法检测不到,执行后可能会出现异常,但这个异常时可以捕获的。
注意:异常发生后,异常之后的代码就不执行了

python中的异常种类

常见的异常种类:

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
二、异常处理: try-except语句

语法结构如下:

try:
    检测范围
except Exception[as reason]:
    出现异常(Exception)后处理的代码

举个例子来说明一下 try-except是怎么使用的

f = open('我是一个不存在的文档.txt')  # 文件不存在将会报错
print(f.read())
f.close()

# output
Traceback (most recent call last):
  File "C:/python文件都在这里/python 全栈/day9-21/day21/2.异常处理.py", line 2, in <module>
    f = open('我是一个不存在的文档.txt')
FileNotFoundError: [Errno 2] No such file or directory: '我是一个不存在的文档.txt'

修改为:

try:
    f = open('我是一个不存在的文档.txt')
    print(f.read())
    f.close()
except OSError:
    print('文件打开的过程中出错啦!')

# output
文件打开的过程中出错啦!

但是从程序员的角度上来说,导致OSError异常的原因有很多(如 FileExistsError、FileNotFoundError、PermissionError等),所以可能会更在意错误的具体内容,这里可以使用as把具体的错误信息给打印出来。

...
except OSError as reason:
    print('文件打开的过程中出错啦!\n错误原因是:', str(reason))
  1. 针对不同异常设置多个except
    一个try语句可以和多个except搭配,分别对感兴趣的异常进行检测处理。
try:
    sum = 7 + '7'  # 注意:该异常语句下面的语句将不会再执行
    f = open('我是一个不存在的文档.txt')
    print(f.read())
    f.close()
except OSError as reason:
    print('文件打开的过程中出错啦!\n错误原因是:', str(reason))
except TypeError as reason:
    print('类型出错啦!\n错误原因是:', str(reason))

# output
类型出错啦!
错误原因是: unsupported operand type(s) for +: 'int' and 'str'
  1. 对多个异常做统一处理
try:
    sum = 7 + '7'
    f = open('我是一个不存在的文档.txt')
    print(f.read())
    f.close()
except (OSError, TypeError) as reason:
    print('出错啦!\n错误原因是:', str(reason))

# output
出错啦!
错误原因是: unsupported operand type(s) for +: 'int' and 'str'
try:
    sum = 7 + '7'
    f = open('我是一个不存在的文档.txt')
    print(f.read())
    f.close()
except TypeError as reason:
    print('出错啦!\n错误原因是:', str(reason))
except OSError as reason:
    print('出错啦!\n错误原因是:', str(reason))

# output
出错啦!
错误原因是: unsupported operand type(s) for +: 'int' and 'str'
  1. 捕获所有异常
    不过通常不建议这么做,因为它会隐藏程序员未想好并未做好准备处理的错误,例如,当用户通过Ctrl + C快捷键强制终止程序,却会被解释为:KeyboardInterrupt异常。
...
except:
	print('出错啦!')
...
...
except Exception as reason:
    print(reason)
...
三、异常处理: try-finally语句

如果在一些场合,就算出现了异常,也不得不执行收尾工作(例如在程序崩溃前保存用户文档),引入了finally来拓展try。

try:
    f = open('我是一个不存在的文档.txt')
    print(f.read())
    sum = 7 + '7'
except:
    print('出错啦!')
finally:
    # f.close()  # 哭,加了这一句报错f没有定义
    print('嘻嘻,别担心,程序停止前我瞧瞧关闭了文件~~')

finally语句块中的内容就是确保无论如何都将被执行的内容。

raise 语句

raise语句用于主动触发异常

>>> raise ZeroDivisionError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError

抛出的异常还可以带参数,表示异常的解释

>>> raise ZeroDivisionError('除数不能为0!!')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: 除数不能为0!!
四、自定义异常
class EvaException(BaseException):
    def __init__(self,msg):
        self.msg=msg
    def __str__(self):
        return self.msg

try:
    raise EvaException('类型错误')
except EvaException as reason:
    print(reason)
五、异常的继承关系
BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    |    +-- FloatingPointError
      |    |    +-- OverflowError
      |    |    +-- ZeroDivisionError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    |         +-- WindowsError (Windows)
      |    |         +-- VMSError (VMS)
      |    +-- EOFError
      |    +-- ImportError
      |    +-- LookupError
      |    |    +-- IndexError
      |    |    +-- KeyError
      |    +-- MemoryError
      |    +-- NameError
      |    |    +-- UnboundLocalError
      |    +-- ReferenceError
      |    +-- RuntimeError
      |    |    +-- NotImplementedError
      |    +-- SyntaxError
      |    |    +-- IndentationError
      |    |         +-- TabError
      |    +-- SystemError
      |    +-- TypeError
      |    +-- ValueError
      |         +-- UnicodeError
      |              +-- UnicodeDecodeError
      |              +-- UnicodeEncodeError
      |              +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
       +-- ImportWarning
       +-- UnicodeWarning
       +-- BytesWarning

异常的继承关系
六、番外:丰富的else语句

1. 要么怎么,要么不怎样

if 条件:
    条件为真执行
else:
    条件为假执行

2. 干完了能怎样,干不完就别想怎样
else可以和 for 和 while 循环语句配合使用,但else语句块只在循环完成后执行,也就是说,如果循环中间使用break 语句跳出循环,那么else里边的内容就不会被执行了。

def show_max_factor(num):
    count = num // 2
    while count > 1:
        if num % count == 0:
            print('%d的最大公约数是%d' % (num, count))
            break
        count -= 1
    else:
        print('%d 是素数!' % num)

3. 没有问题?那就干吧
else 语句和异常处理搭配:只要try 语句块里没有出现任何异常,那么就是执行else语句块的内容。

try:
    int('jacky')
except ValueError as reason:
    print('出错啦!' + str(reason))
else:
    print('没有任何异常!')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值