异常处理

一:元类补充

  __new__与__init__的区别:

    __new与__init__先执行,其作用是创建一个空的对象,作为一个类的对象,必须具备三个组成部分,所以调用type中的__new__来完成组装,得到这个类对象后需要将其返回,以供__init__来使用。

class MyMeta(type):
    # 用于新建类对象
    def __new__(cls, *args, **kwargs):
        print("new run")
        # print(MyMeta)
        # print(*args)
        # 调用type通过的__new__方法来创建一个空的类对象 已经将三个组成部分都放到类对象中了
        res = type.__new__(cls,*args)
        return res
    def __init__(self,class_name,bases,namespace):
        print("init run")
        print(self)
class Student(metaclass=MyMeta):
    pass

print(Student)
__new__

二:异常处理

  1:什么是异常?

    异常指的就是程序运行时发生的错误(在程序出现错误时,则会产生下一个异常,如果程序没有处理它,则会抛出该异常,代码也就不再继续运行下去了)。在python中,错误触发的异常有多种,示例如下:

错误分为两种:一种是语法错误(这种错误根本过不了python解释器的语法检测,必须在程序执行前就改正),另一种就是逻辑错误。

#TypeError:int类型不可迭代
for i in 3:
    pass
#ValueError
num=input(">>: ") #输入hello
int(num)

#NameError
aaa

#IndexError
l=['egon','aa']
l[3]

#KeyError
dic={'name':'egon'}
dic['age']

#AttributeError
class Foo:pass
Foo.x

f = open("1.今日内容")
f.close()
f.read()
#ValueError: I/O operation on closed file.   文件已经关闭  你还要去读写

def func():
 print(1)
  print(2)
# IndentationError: unexpected indent   缩进错误

#ZeroDivisionError:无法完成计算
res1=1/0
res2=1+'str'
逻辑错误

  2.异常的种类

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

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

  3.异常处理

    3.1如果错误的发生条件是可预知的,我们需要进行if进行处理,在错误发生之前进行预防。

AGE=10
while True:
    age=input('>>: ').strip()
    if age.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
        age=int(age)
        if age == AGE:
            print('you got it')
            break
if处理异常

    3.2如果错误的发生条件是不可预知的,则需要用到try...except:在错误发生之后进行处理。

基本语法为:
try:
    被检测的代码块
except 异常类型:
    try中一旦检测到异常,就执行这个位置的逻辑

例如:
try:
    print('beginning')
    a=int('abc')
    print('error')

except ValueError:
    print('发生了ValueError异常')
print('over')


=======================================
>>>:
beginning
发生了ValueError异常
over
基本语法
# 语法1
try:
     # 把可能发出错误的代码放到try中
    print("start")
    # a = int("abc")
    li[1]
    print("over")

except ValueError:
    # 当try中真的发生了错误 就会执行 except中的代码
    # 在这里可以做一些补救措施
    print("发生了 ValueError异常")

print("over")
1.异常类只能用来处理指定的异常情况,非指定异常无法处理
# 语法2 except可以有多个
try:
     # 把可能发出错误的代码放到try中
    print("start")
    a = int("abc")
    li[1]
    print("over")

except ValueError:
    # 当try中真的发生了错误 就会执行 except中的代码
    # 在这里可以做一些补救措施
    print("发生了 ValueError异常")
except IndexError:
    print("发生了 IndexError  索引不正确")
print("over")
2.try...多个except,但是只执行一个except
语法3  万能异常 Exception类  尽量少用 可能会导致 程序既不报错 也不正常运行 无法定位错误位置
# try:
#      # 把可能发出错误的代码放到try中
#     print("start")
#     # a = int("abc")
#     # li[1]
#     dic = {}
#     dic["name"]
#     print("over")
# 
# except Exception:
#     print("可能是任何类型的错误 反正是发生错误了")
# print("over")


#但是具体不知道是发生了什么错误,尽量少用,可能会导致程序既不报错,也不正常运行,无法定位错误位置。
3.万能异常
语法4 万能异常 Exception类  建议 输出异常的值
# try:
#      # 把可能发出错误的代码放到try中
#     print("start")
#     # a = int("abc")
#     # li[1]
#     dic = {}
#     dic["name"]
#     print("over")
# 
# # 可以通过给异常取别名 来获取异常的对象  对象中包含了错误信息
# except Exception as e:
#     print("可能是任何类型的错误 反正是发生错误了")
#     print(e)
#     print(type(e))
# print("over")



#建议将异常类型打印出来
4.建议输出异常类型的值
# 语法5 先捕获能够明确的异常类型 最后捕获万能异常类型
try:
     # 把可能发出错误的代码放到try中
    print("start")
    # a = int("abc")
    # li[1]
    # 10 / 0
    dic = {}
    dic["name"]
    print("over")
except ValueError:
    print("值不对.....")
except ZeroDivisionError:
    print("除数不能为0")
# 可以通过给异常取别名 来获取异常的对象  对象中包含了错误信息
except Exception as e:
    print("可能是任何类型的错误 反正是发生错误了")
    print(e)
    print(type(e))

print("over")


#建议将万能异常放在最后执行,等其他异常执行完之后没有捕捉到异常才会执行万能异常。
5.多分支和万能异常
# 语法6 try except else
try:
     # 把可能发出错误的代码放到try中
    print("start")
    # a = int("abc")
    # li[1]
    # 10 / 0
    dic = {}
    # dic["name"]
    print("over")
except ValueError:
    print("值不对.....")
except ZeroDivisionError:
    print("除数不能为0")
# 可以通过给异常取别名 来获取异常的对象  对象中包含了错误信息
except Exception as e:
    print("可能是任何类型的错误 反正是发生错误了")
    print(e)
    print(type(e))
else: #当没有发生异常会执行else    只能except的后面
    print("执行了else")
print("over")
6.try except else
# 语法7 try except finally
try:
     # 把可能发出错误的代码放到try中
    print("start")
    # a = int("abc")
    # li[1]
    # 10 / 0
    dic = {}
    # dic["name"]
    print("over")
except ValueError:
    print("值不对.....")
finally: #无论是否发生异常 最后都会执行finally中的代码
    print("finally")
print("over")
7.try except finally
import io
# finally的使用场景  可以用finally来执行一些清理操作  类似__del__
try:
    print("start")
    f = open("1.今日内容","rt",encoding="utf-8")
    f.read()
    print("end")
except FileNotFoundError:
    print("文件路径错误...")
except io.UnsupportedOperation:
    print("文件不能被写入....")
finally:
    f.close()
print(f.closed)
finally的使用场景
"""
    做一个登录功能   如果登录失败就抛异常
"""
# 主动抛出异常
# 当你写了一些功能 是提供给别人用的 然而使用者不按照你的方式来使用,就会导致程序出错
# 而且我们无法帮助用户处理这个错误
# 这时候就可以主动抛出异常
# raise 关键字  后面跟 任意Exception类型的子类

# 自定义异常类型
class LoginException(Exception):
    pass

def login():
    name = input("username:").strip()
    pwd = input("password:").strip()

    if name == "Grace" and pwd == "123":
        print("登录成功!")
    else:
        raise LoginException("用户名或密码不正确....")

login()
8.自定义异常类型

  4.断言

    断言就是很确定某个条件一定成立(有一段代码,要执行就必须要保证某个条件是成立的)。使用断言来简化代码,断言后面跟一个bool类型表达式,如果为True则继续往下执行,否则抛出异常,其局限性是:异常类型是固定的,而且不能指定异常信息。

#断言条件
#assert 1==1 (true)
#assert 1==2 (false)


names = ["张三","李四","王麻子"]
names=[]

assert  1

print('正在处理数据')
print('正在处理数据')
print('正在处理数据')
print('正在处理数据')
print('正在处理数据')
print('正在处理数据')
断言

 

posted @ 2018-12-20 16:08  刘小鹿  阅读(171)  评论(0编辑  收藏  举报