python学习笔记14(异常)

一、上堂回顾

1.默写题目

1.简述类属性和实例属性之间的区别

a.定义的位置
b.访问方式不同
c.在内存中出现的时机不同
d.优先级不同

2.简述成员方法,类方法和静态方法之间的区别

a.语法
b.调用方式
c.在继承关系中【相同点】

3.采用装饰器的方式书写一个单例设计模式

#1.闭包
def singleton(cls):
    #2.单例的实现思路
    instance = {}
    def getInstance(*args,**kargs):
        if cls not in instance:
            instance[cls] = cls(*args,**kargs)
        return instance[cls]
    return getInstance
​
@singleton
class Person(object):
    pass        

2.知识点回顾

1.重写:【override】

​ 在继承的类中,在子类中将函数重新实现一次

2.重载:[overload]

​ 将系统的内置函数重新实现一次

3.多态

​ 父类的引用指向子类的对象

​ 重写和重载都是多态的体现形式

4.获取对象信息

​ type()

​ isinstance() 一般用在if语句中

作业:

textDemo01.py

"""
3.使用封装的思想结合列表完成下面题目
    学生类:姓名、年龄、学号、成绩
    班级类:班级名称、学生列表
        显示所有学生
        根据学号查找学生
        添加一个学生
        删除一个学生(学生对象、学号)
        根据学号升序排序
        根据成绩降序排序
"""
from  homework.student import Student
from homework.grade import Grade
​
#1.创建学生对象
stu1 = Student("小明",10,1001,80)
stu2 = Student("jack",20,1003,60)
stu3 = Student("bob",15,1002,99)
stu4 = Student("tom",30,1004,75)
​
#2.创建班级对象
gra = Grade("三年一班",[stu1,stu2,stu3,stu4])
​
#3.调用功能
gra.showAll()
gra.searchBystuid(1002)
​
stu5 = Student("abc",25,1005,80)
gra.addStu(stu5)
​
#gra.delStu(1003)
​
#gra.sortBystuid()
gra.sortByScore()

student.py

class Student(object):
    def __init__(self,name,age,stuid,score):
        self.name = name
        self.age = age
        self.stuid = stuid
        self.score = score
​
    def __str__(self):
        return  "%s %d %d %d" %(self.name,self.age,self.stuid,self.score)

grade.py

class Grade(object):
    def __init__(self,name,stulist):
        self.name = name
        self.stulist = stulist
​
    #显示所有学生
    def showAll(self):
        print("所有学生的信息为:")
        for stu in self.stulist:
            print(stu)
    #根据学号查找学生
    def searchBystuid(self,stuid):
        for stu in self.stulist:
            if stuid == stu.stuid:
                print("搜索结果如下:")
                print(stu)
    # 添加一个学生
    def addStu(self,stu):
        self.stulist.append(stu)
        print("添加之后的学生如下:")
        self.showAll()
    # 删除一个学生(学生对象、学号)
    def delStu(self,stuid):
        for stu in self.stulist:
            if stuid == stu.stuid:
                self.stulist.remove(stu)
​
        print("删除之后的学生如下:")
        self.showAll()
    # 根据学号升序排序
    def sortBystuid(self):
        for i in range(0,len(self.stulist) - 1):
            for j in range(0,len(self.stulist) - i - 1):
                if self.stulist[j].stuid > self.stulist[j + 1].stuid:
                    self.stulist[j],self.stulist[j + 1] = self.stulist[j + 1],self.stulist[j]
​
        print("排序之后的结果为:")
        self.showAll()
    # 根据成绩降序排序
    def sortByScore(self):
        for i in range(0,len(self.stulist) - 1):
            for j in range(i + 1,len(self.stulist)):
                if self.stulist[i].score < self.stulist[j].score:
                    self.stulist[i],self.stulist[j] = self.stulist[j],self.stulist[i]
        print("排序之后的结果为:")
        self.showAll()

二、错误和异常

1.概念

有两种错误很容易辨认:语法错误和异常

异常:代码没有出现错误,但是,当程序 运行起来之后,会在控制台上报出错误,这种错误就被称为异常

异常的特点:当程序在执行过程中遇到异常,而且异常没有被处理,则程序会终止在出现异常的地方,代码不会继续向下执行

解决问题:当程序遇到异常的时候,让程序越过异常继续向下执行

本质【工作机制】:只是将异常屏蔽掉,不要影响其他代码的执行,并没有真正的处理

2.常见异常

AttributeError:指定对象没有指定的属性

StopIteration:迭代器没有更多的值进行遍历

ZeroDevisionError:不能除以或者取模0

KeyError:字典中没有指定的键

NameError:没有声明或者初始化变量【某个对象没有某个指定的属性】

UnboundLocalError:访问未初始化的本地变量

SyntaxError:Python语法错误

TypeError:对类型进行无效的操作

3.异常处理方式【掌握】

异常处理的方式:捕获和抛出

3.1try-except-else

语法:

try:

​ 语句

except 错误表示码1 as 变量名:

​ 语句1

except 错误表示码2 as 变量名:

​ 语句2

......

else:

​ 语句n

说明:

​ a.try对应的代码块被称为代码监测区域,用来监测其中的代码是否有异常【将可能存在异常的代码写在try代码块中】

​ b.如果try中的代码出现了异常,则try中的代码会终止在出现异常的代码处,则直接执行except代码块,具体执行哪个except代码块,取决于出现了什么样的异常

​ 注意:此处的except块并不是真正处理了异常,只是做了屏蔽【拦截】,可以让后面的代码正常执行

​ c.else可有可无,根据具体的需求而定

代码演示:

#1.使用except带一个异常类型
try:
    #可能存在异常的代码
    #num = int(input("请输入一个数字:"))
    #print(10 / num)
    pass
except ZeroDivisionError as e:
    #此处的e就相当于一个ZeroDivisionError的对象
    #注意:所有异常的类中将__str__重写过了,返回一个异常的描述字符串
    print(e)   #division by zero
​
print("hello")
​
#2.使用多个except异常类型
#工作原理;如果try中代码出现了异常,则在except分支中从上往下挨个进行匹配错误码,如果匹配上了,则整个try-except结束
try:
    #可能存在异常的代码
    #num = int(input("请输入一个数字:"))
    #print(10 / num)
    pass
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except ZeroDivisionError as e:
    print(e)   #division by zero
except UnboundLocalError as e:
    print(e)
​
#3.except不带任何异常类型
#工作原理:不管try中出现什么样的异常,都会执行except块
try:
    #可能存在异常的代码
    #num = int(input("请输入一个数字:"))
    #print(10 / num)
    pass
except:
    print("出现了异常")
​
​
#4.一个except后面可以跟多种错误码
#工作原理;只要try中出现的异常匹配上元组中的任意一个错误码即可
try:
    #print(10 / 0)
    pass
except (ZeroDivisionError,KeyError,ValueError):
    print("出现了异常")
​
#5.else分支
#工作原理:只有当try中的代码没有异常出现的时候,才会执行else分支
try:
    print(10 / 5)
except (ZeroDivisionError,KeyError,ValueError):
    print("出现了异常")
else:
    print("else被执行了")
​
#6.除了在try中直接检测可能存在异常的的代码,也可以检测可能存在异常的代码所在的函数
def test():
    print(10 / 0)
​
try:
    #test()
    pass
except ZeroDivisionError as e:
    print(e)
​
#7.所有异常的父类是BaseException【Exception】,如果BaseException出现在except语句的第一个,则直接会被执行
try:
    print(10 / 0)
​
except BaseException as e:
    print("~~~~~")
    print(e)
except ZeroDivisionError as e:
    print(e)

3.2try-except-finally

作用:一般用来定义清理行为,表示代码执行完成之后都需要做的清理行为

语法:

try:

​ 语句

except 错误表示码1 as 变量名:

​ 语句1

except 错误表示码2 as 变量名:

​ 语句2

......

finally:

​ 语句n

说明:区别于else分支,不管try中代码有没有异常,finally块都会被执行

代码演示:

#1.直接使用
try:
    print(10 / 5)
​
except BaseException as e:
    print(e)
​
finally:
    print("finally被执行了")
​
#2.特殊情况
#注意:如果在try-except-finally语句中,在try或者except语句中出现return,finally仍然会被执行
#使用场景:文件关闭,数据库关闭,为了避免资源的浪费
def show():
    try:
        print(10 / 4)
        return
    except BaseException as e:
        print(e)
​
    finally:
        print("finally被执行了~~~~~~")
​
show()
​
print("&&&&&&&&&&&&&&7")
​
#3.特殊情况:如果try中的异常没有匹配到相应的except语句,那么这个异常会在finally执行之后再次出现
try:
    print(10 / 0)
except KeyError as e:
    print(e)
​
finally:
    print("over")
"""
Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/XA-Python1804/Day14Code/exception/try-exceptDemo02.py", line 30, in <module>
    print(10 / 0)
ZeroDivisionError: division by zero
"""

3.3抛出异常

raise:抛出一个异常

代码演示:

#语法:raise  异常对象 ======》等价于实实在在存在的一个异常 10 / 0
#异常错误码("异常的信息描述")
​
try:
    raise NameError("变量没有被初始化")
except NameError as e:
    print(e)
​
#raise表示实实在在的抛出了异常,为了不影响其他代码的执行,最终还是要通过try-except进行捕获
#raise的使用场景:自定义异常中

3.4assert断言【了解】

代码演示:

def fun(num,divnum):
​
    #断言
    #预言:预言成功,则获取结果,预言失败,则出现一个AssertionError异常,异常的信息描述是自定义的
    assert (divnum != 0),"除数或者分母不能为0"
    return num / divnum
​
​
#print(fun(10,4))
print(fun(10,0))

4.异常嵌套

try中嵌套try

except中嵌套try:常用

代码演示:

print("我想去拉萨")
​
try:
    print("我准备乘飞机过去")
    raise Exception("由于天气大雾,飞机无法起飞")
    print("到拉萨了,拉萨真漂亮")
​
except Exception as e:
    print(e)
​
    try:
        print("我准备乘火车过去")
        raise Exception("由于大暴雨,铁路断了")
        print("到拉萨了,拉萨真漂亮")
​
    except Exception as e:
        print(e)
        print("我骑自行车去")
        print("到拉萨了,拉萨真漂亮")

5.自定义异常

实现步骤:

​ a.自定义一个类,继承自Exception类或者BaseException

​ b.书写构造函数,设置一个参数,用于保存异常信息

​ c.重写str函数,返回异常信息

​ d.定义一个成员函数,用来处理异常

代码演示:

class MyException(Exception):
    def __init__(self,msg):
        #调用父类中的构造函数,目的是将系统的异常机制引用过来
        super(MyException,self).__init__()
        self.msg = msg
​
    def __str__(self):
        return self.msg
​
    def handle(self):
        print("处理异常")
​
​
try:
    raise MyException("自己的异常类型")
except MyException as e:
    print(e)
    e.handle()

三、文件读写【掌握】

1.概述

Python中内置了文件读写的功能

现代的系统不允许普通的程序直接访问磁盘的,所以,读写磁盘上的文件首先会请求打开一个文件的对象【也被称为文件描述符】,然后,通过系统提供的功能就可以读写文件

2.读文件

2.1过程

a.打开文件:open()

b.读取文件内容:read()

c.关闭文件:close()

​ 注意;文件使用完毕之后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统在同一个时间段内打开的文件是有限的

2.2使用

代码演示:

#一、打开文件
"""
open(path,flag[,encoding,errors])
path:需要读取的文件的路径【相对路径和绝对路径】
flag:打开方式
    r:只读的方式打开,注意:读取的文件必须存在
    rb:以二进制的形式打开一个文件,用于只读,注意:读取的文件必须存在
    r+:打开一个文件用于读写,注意:读取的文件必须存在
​
    w:只能写入内容,注意:如果该文件存在则覆盖,如果不存在则会自动创建
    wb:以二进制的方式打开一个文件,用于写入,注意:如果该文件存在则覆盖,如果不存在则会自动创建
    w+:打开一个文件用于读写,注意:如果该文件存在则覆盖,如果不存在则会自动创建
​
    a:打开一个文件,向其中追加内容
​
    说明:rb和wb 表示使用二进制的形式打开文件,主要用来打开多媒体资源【图片,视频,音频等】
encoding:编码格式,可写可不写
errors:错误处理,可写可不写
"""
#注意:encoding一般使用关键字参数传参;打开文件的时候采用的编码格式必须和文件本身的编码格式一致,否则出现乱码
f = open("致橡树.txt","r",encoding="gbk")
print(f)
​
"""
1.当使用r的方式打开文件的时候,后面的encoding可加可不加
    如果文件的格式为gbk的,可以不加
    如果文件的格式时utf-8的,最好加上encoding="utf-8"
2.当使用rb/wb的方式打开文件的时候,后面的encoding不添加
"""
​
#二、读取文件内容
#1.一次性读取全部的内容
#str1 = f.read()
#print(str1)
​
#2.读取指定字符数
#如果不指定参数,则一次性读取全部的内容,如果指定参数,以字符串返回指定数量的数据,并且每一行的结尾都有一个换行符"\n"
#str2 = f.read(5)
#print(str2)
​
#3.读取整行
#注意:不管一行有多少个字符,一次性读取一行,以"\n"作为参照进行换行
# readline()
"""
str3 = f.readline()
print(str3)
str3 = f.readline()
print(str3)
str3 = f.readline()
print(str3)
str3 = f.readline()
print(str3)
"""
​
#4.读取一行中前指定的字符
str4 = f.readline(3)
print(str4)
str4 = f.readline(3)
print(str4)
str4 = f.readline(3)
print(str4)
​
#5.读取所有行并返回列表,显式的出现\n
#readlines()
str5 = f.readlines()
print(str5)
​
#三、关闭文件
f.close()
​
​
#一个完整的过程
try:
    f1 = open("致橡树.txt","r",encoding="gbk")
    print(f1.read())
except FileNotFoundError as e:
    print(e)  #找不到指定的文件路径
    #f1  = None
except LookupError as e:
    print(e)  #指定了未知的编码
except UnicodeDecodeError as e:
    print(e) #读取文件的时候解码错误
finally:
    if f1:
        f1.close()
​
#简写方式
#好处:不需要手动调用close关闭文件,文件读取完成之后会自动关闭
with open("致橡树.txt","r",encoding="gbk") as f:
    print(f.read())

3.写文件

3.1过程

a.打开文件:open()

b.将数据写入缓存:write()

c.刷新文件内部缓存:flush()

d.关闭文件:close()

3.2使用

代码演示:

#注意:向一个文件中写入内容,文件可以不存在,会自动创建
​
path = "file1.txt"
#1.打开文件   wb   a
#注意:w表示将原来的内容全部替换,a表示在文件末尾进行追加
f = open(path,"a",encoding="gbk")
​
#2.写入数据
#注意:如果写入文件的数据需要换行的话,则需要手动添加\n
f.write("hello写入文件的数据需要换行的话")
​
#3.刷新缓冲区【加速数据的流动,保证缓冲区的畅通】
#直接将内部缓冲区的内容立刻写入文件,而不是被动的等待自动刷新写入
f.flush()
​
#4.关闭文件
f.close()
​
#简写形式
"""
with open(path,"w",encoding="utf-8") as f:
    f.write("")
    f.flush()
"""

4.编码和解码

字符串类型和字节类型之间的转换

​ 字符串类型转换为字节类型:编码【encode】

​ utf-8: 存储中文3个字节

​ gbk;存储中文2个字节

​ 字节类型转换为字符串类型:解码【decode】

注意:保证设置的编码格式和文件的编码格式相符,否则出现乱码

代码演示:

​
path = r"file2.txt"
​
#编码:字符串----》字节
with open(path,"wb") as f1:
    s1 = "今天是个好日子,today is a good day"
    f1.write(s1.encode("utf-8"))
    f1.flush()
​
#解码:字节----》字符串
with open(path,"rb") as f2:
    data = f2.read()
    print(data)
    print(type(data))
​
    newData = data.decode("utf-8")
    print(newData)

5.练习

代码演示:

# 需求:需求文件内容的拷贝
import  os

def myCopy(srcPath,desPath):
    #判断源文件是否存在
    if not os.path.exists(srcPath):
        print("源文件不存在")
        return

    #判断源路径是否是文件
    if not os.path.isfile(srcPath):
        print("源路径是文件夹,不是文件")
        return

    #打开文件
    srcFile = open(srcPath,"rb")
    desFile = open(desPath,"wb")

    #获取源文件的大小
    size = os.path.getsize(srcPath)
    #循环读取文件,并将读取出来的内容写入到目标文件中
    while size > 0:
        content = srcFile.read(1024)
        desFile.write(content)
        desFile.flush()
        size -= 1024

    #关闭文件
    srcFile.close()
    desFile.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值