python 异常

什么是异常


异常是程序发生错误的信号,一旦程序出错python解释器就会产生一个异常

如果该异常没有被处理,该异常就会抛出来,程序的运行也随即终止

为什么要处理异常


增强程序的健壮性(鲁棒性)

如何处理异常


具体来说错误分为两大类:

	1、语法错误:这种错误在程序运行前就必须改正确,不允许出现
    
		SyntaxError
    
	2、逻辑错误:程序运行时才会遇到逻辑错误

		1、尽量避免
        	针对可以控制的逻辑错误,应该直接在代码层面解决
            
		2、针对无法预防的错误,解决方案--》补救
        	针对不可以控制的逻辑错误,应该采用try...except...:一种异常产生之后的补救措施
        
可以控制的逻辑错误:
# 如果错误发生的条件是可预知的,我们需要用if进行处理:在错误发生之前进行预防
age = input(">>>: ").strip()
if age.isdigit():
    age = int(age)

    if age > 19:
        print('too big')
    elif age < 19:
        print('too small')
    else:
        print('you got it')
else:
    print('必须输入数字')
不可以控制的逻辑错误:
# 如果错误发生的条件是不可预知的,则需要用到try...except:在错误发生之后进行处理
# 如何用try...except
"""
print('start...')
try:
    被监测的代码块1
    被监测的代码块2
    被监测的代码块3
    被监测的代码块4
    被监测的代码块5
except 异常的类型1 as e:
    处理异常的代码
except 异常的类型2 as e:
    处理异常的代码
except 异常的类型3 as e:
    处理异常的代码
except (异常的类型4,异常的类型5,异常的类型6) as e:
    处理异常的代码
except Exception:    # 万能异常,当上面所有的异常处理都对不上最终运行此异常处理
    处理异常的代码
else:
    没有发生异常时要执行的代码
finally:
    无论异常与否,都会执行该代码,通常用来进行回收资源的操作
print('end...')

"""


# 案例1
print('start...')

try:
    print(111)
    print(222)
    l=[11,22,33]
    l[100]       # 异常:list index out of range 列表索引超出范围
    print(3333)
except IndexError as e: # 捕捉异常匹配成功并打印e,程序不会崩
    print(e)

print('end...')


# 案例2
print('start...')

try:
    print(111)
    print(222)
    l=[11,22,33]
    l[100]
    print(3333)
except KeyError as e:  # 异常对不上没有匹配成功,程序就崩了
    print(e)

print('end...')


# 案例3
print('start...')

try:
    print(111)
    print(222)
    l=[11,22,33]
    l[0]
    dic = {'k1':111}
    # dic['kkkkk']
    print(3333)
except Exception as e:  # 万能异常,什么异常都能对上
    print(e)
else:  # try内代码块没有异常则执行
    print('else的代码')
finally:      #  无论异常与否,都会执行该模块,通常是进行清理工作
    print('====>finally的代码')

print('end...')


l=[]
l[100]
>>> IndexError: list index out of range # 列表索引超出范围
    
dic={}
dic["k1"]
>>> KeyError: 'k1' 
    
class Foo:
    pass
obj = Foo()
obj.x
>>> AttributeError: 'Foo' object has no attribute 'x'  # Foo对象没有属性x
    
int("asdb")    # 无效的int()的基数为10:'asdb'
>>> ValueError: invalid literal for int() with base 10: 'asdb'
        
1/0  
>>> ZeroDivisionError: division by zero # 零除法错误:被零除法
    
    
def func(x):
    pass

func()        # func()缺少1个必需的位置参数:'x'
>>> TypeError: func() missing 1 required positional argument: 'x'

x
>>> NameError: name 'x' is not defined   # 名字'x'没有定义
    
print('asdfadf'
>>> SyntaxError: unexpected EOF while parsing  # 解析时意外的EOF:语法错误
      
      



     
try:
    print('你好')
    print('Ni'[2])
    print('我能运行吗')
    
except IndexError as a:
    print('异常!', a)

else:
    print('程序居然不报错?')

finally:
    print('程序异常不异常与我无关,我必活')

# 你好
# 异常! string index out of range
# 程序异常不异常与我无关,我必活

如何抛异常

      
    
# 断言:判断条件达到标准,如果不达到标准就抛出异常(测试程序的时候可以用,测试完后应该删掉)
l = [111,222]
if len(l) != 3:    # 判断如果l长度不等于3  方式一
    raise Exception('必须达到三个值')  # Exception: 必须达到三个值 
      
assert len(l)  == 3  # 断定l长度等于3  方式二,跟方式一效果一样
print('后续代码。。。')

# raise  # 主动抛出异常,为别人定规则的时候就可以用到主动抛异常
raise IndexError("索引错误")  # IndexError: 索引错误

# 自定义异常
# 自定义一个权限相关的错误,继承一下内置的异常类型(BaseException:基本的异常)

class Permission(BaseException): 
    def __init__(self,msg): # 自定义的还可以加其他功能
        self.msg = msg

raise Permission("权限错误") # 自定义异常通常配合raise使用,自己抛出自定义的异常,提示效果更强
# __main__.Permission: 权限错误


class liufeipengError(BaseException):
    pass


class Student:

    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        if type(name) is str:
            self.__name = name
        else:
            raise liufeipengError


stu = Student('刘鹏飞')

print(stu.name)

stu.name = 123  # __main__.liufeipengError
  • 异常的种类

  • 在python中不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,一个异常标识一种错误


# 常见异常

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x

IOError 输入/输出异常;基本上是无法打开文件

ImportError 无法引入模块或包;基本上是路径问题或名称错误

IndentationError 语法错误(的子类) ;代码没有正确对齐

IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

KeyError 试图访问字典里不存在的键

KeyboardInterrupt Ctrl+C被按下

NameError 使用一个还未被赋予对象的变量

SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
                              
TypeError 传入对象类型与要求的不符合
                              
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
                              
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
                              
posted @ 2021-06-07 11:14  此用户名不可用  阅读(105)  评论(0)    收藏  举报