Day10

一、上堂回顾

1.默写题目

1.实现文件内容的拷贝

def customCopy(src_path,des_path):
  #with....as类似于if语句,while语句,不会引入新的作用域
  
  #读取
  with open(src_path,"rb") as f1:
    content = f1.read()
  #写入
  with open(des_path,"wb") as f2:
    f2.write(content)
    f2.flush() 
    
  #注意:操作的编码格式和文件本身的编码格式要一致

2.使用装饰器方式书写一个单例类

def singleton(cls):
  #临时变量/自由变量
  instanceDict = {}
  def currentInstance(*args,**kwargs):
    if cls not in instanceDict:
      	instanceDict[cls] = cls(*args,**kwargs)   #调用cls代表的那个类的构造函数
        
    return instanceDict[cls]    	
  return currentInstance

@singleton
class Text(object):
  pass

2.知识点回顾

装饰器实现单例问题补充:

#方式一None
def singleton(cls):
    #函数作用域
    instance = None
    def getInstance(*args,**kwargs):
        #UnboundLocalError: local variable 'instance' referenced before assignment
        nonlocal instance
        if not instance:
            #局部作用域
            instance = cls(*args, **kwargs)
        return instance

    return  getInstance

@singleton
class Test(object):
    pass

t1 = Test()

#方式二:字典
def singleton(cls):
    # 临时变量/自由变量
    instanceDict = {}

    def currentInstance(*args, **kwargs):

        if cls not in instanceDict:

            instanceDict[cls] = cls(*args, **kwargs)  # 调用cls代表的那个类的构造函数

        return instanceDict[cls]

    return currentInstance


@singleton
class Text(object):
    pass

二、csv文件读写【掌握】

csv:Comma Separated Values,逗号分隔值

.csv文件类似于.txt文件,是一种特殊的纯文本的文件格式

特点:字符之间使用逗号或者tab键隔开,主要不同程序之间进行数据的交互

注意:在Windows下可以使用excel,文本文档,notepad++,subline等打开

用法:需要导入模块csv

1.读取csv文件

#第一步:导入模块
import  csv

#第二步:三步曲
def readCsv1(path):
    #1.打开文件
    csvFile = open(path,"r")
    #2.将文件对象转化为可迭代对象【读取内容】
    csvReader = csv.reader(csvFile)
    #print(csvReader)
    #print(type(csvReader))

    #3.获取内容,可迭代对象中存储的是列表【一行内容为一个列表】
    infoList = []
    for item in csvReader:
        print(item)
        infoList.append(item)

    #print(infoList)

    #4.关闭文件【使用文件对象调用close函数】
    csvFile.close()

    return infoList

#第三步:简写方式
def readCsv2(path):
    infoList = []
    with open(path,"r") as csvFile:
        csvReader = csv.reader(csvFile)
        for item in csvReader:
            infoList.append(item)

    return  infoList

#第四步:采用普通文件的方式读取
#注意:可以读取,但是读取的是普通的文本,如果采用csv特有的方式读取,读取到的是一个列表
def readCsv3(path):
    with open(path,"r") as f:
        resust = f.read()
        print(resust)

if __name__ == "__main__":
    path = r"file1.csv"
    readCsv3(path)

2.写入csv文件

#第一步:导入模块
import csv

#第二步:写入数据
def writeCsv1(path):

    #1.打开文件
    #注意:默认每写入一行,则会在该行的后面他添加一个空行\n,可以使用newline消除空行
    csvFile = open(path,"w",newline="")

    #2.将文件对象进行转换
    csvWriter = csv.writer(csvFile)

    #3.将数据写入
    #a.可以直接写入一维列表
    #list1 = ["111","2222","333"]
    #csvWriter.writerow(list1)

    #b.写入二维列表
    # infoList = [['username', 'password', 'age', 'address'], ['zhagnsan', 'abc123', '18', 'china'],
    #             ['lisi', 'aaa', '16', 'xian'],
    #             ['wangwu', 'dhdh', '21', 'shenzhen']]
    # for subList in infoList:
    #     csvWriter.writerow(subList)

    #c.写入字符串
    #注意:writerow写入字符串,得到的结果为字符之间使用逗号隔开,但是使用write直接将整个字符串写入
    #csvWriter.writerow("helloabcdef")

    #d.写入一个字典
    dict1 = {"zhangsan":10,"lisi":19,"wangwu":17}
    for key in dict1:
        csvWriter.writerow([key,dict1[key]])

    #4.关闭文件
    csvFile.close()


#第三步:简写形式
def writeCsv2(path):
    list1 = ["111", "2222", "333"]
    with open(path,"w",newline="")  as csvFile:
        csvWriter = csv.writer(csvFile)
        csvWriter.writerow(list1)

#第四步:使用普通方式写入csv文件
#可以写入,但是写入的是一个普通的字符串
def writeCsv3(path):
    with open(path, "w")  as csvFile:
        csvFile.write("hello")
        csvFile.flush()

if __name__ == "__main__":
    path = r"file2.csv"
    writeCsv3(path)

三、枚举类【了解】

枚举类型可以看做是一种标签或者是一系列常量的集合,常用于表示某些特定的有限的集合,例如:星期,月份,国家

Python3.4之前,没有枚举数据类型,但是,可以采用字典,类实现

#1.字典
WEEKDAY = {
    "MON":1,
    "TUS":2,
    "WED":3
}
WEEKDAY["MON"] = 188

#2.类
class Weekday(object):
    #类属性
    MON = 1
    TUS = 2
    WED = 3


print(Weekday.MON)
print(type(Weekday.MON))
Weekday.MON = 188

Python3.4之后,新增了特性:枚举类【enum标准库】,在3.4之前如果想要使用enum库则需要通过pip install enum安装

"""
enumerate()
枚举其实是一个容器,其中存储的数据被称为枚举成员/枚举常量

enum提供了
    Enum类:用于充当父类,自定义自己的枚举类
    IntEnum类:用于充当父类,限定枚举成员必须为整数类型或者可以转换为整数类型
    unique装饰器:限定枚举成员的值不可重复,只能是唯一的
"""
from enum import Enum,IntEnum,unique

#1.Enum的使用
#枚举中存储的是枚举常量,所以枚举类和其中类属性的命名一般采用的是全大写
class WEEKDAY(Enum):
    #枚举成员/枚举常量/枚举实例
    MON = 1
    TUS = 2
    WED = 3
    THU = 4
    FRI = 5
#注意:区别于普通类中中类属性,访问实质上是当前枚举类的实例,而不是普通类中的普通类型【整型,字符串,布尔值】
print(WEEKDAY.MON)
print(WEEKDAY.MON.THU)
print(WEEKDAY.MON.THU.WED.FRI)
print(type(WEEKDAY.MON))

#注意:枚举成员是不可变的
#WEEKDAY.MON = 19
#ttributeError: Cannot reassign members.   assignment

#2.IntEnum的使用
class COLOR(IntEnum):
    RED = 0
    BLUE = 1
    GREEN = "2"

#枚举成员本事就是当前枚举类的对象,而且每个枚举成员都是一个单例,只能被获取,不能进行修改
print(COLOR.RED)
COLOR(
print(1))   #RED = COLOR(0)
print(COLOR(0))


#3.unique的使用
@unique
class COLOR(IntEnum):
    RED = 0
    BLUE = 1
    GREEN = 0   #ValueError: duplicate values found in : GREEN -> RED

print(COLOR(0))

四、异常

1.概念

Python中有两种错误很容易辨认:语法错误【解析错误】和异常

语法错误:在pycharm中,立即报错

异常:代码正常,运行之后才会出错

异常:一种可能性

异常处理:只是将可能性考虑到,将错误屏蔽掉,保证后面的代码正常执行

num = 10
print(num)

#特点:一旦程序中出现异常,并且该异常未被处理,则代码将停止,后面的代码没有执行的机会
#需要解决的问题:当程序遇到异常时,不让程序结束,接着向下执行
print(num / 0)

print("over")

2.常见异常

AttributeError:一个对象试图访问了一个不存在的属性或者方法

IOError:输入/输出异常,读写文件的过程中基本上无法打开文件

ImportError:导入模块的时候异常;基本上是路径或者名称错误

IndexError:列表或者元组或者字符串的下标越界

KeyError:试图访问不存在的key

ValueError:传入一个不期望的值

TypeError:传入的数据类型不匹配

NameError:使用了一个未被定义的变量

UnboundLocalError:使用了还未被定义的局部变量:基本上由于存在另外一个同名的全局变量,你正在访问的时候【nonlocal global】

SyntaxError;代码非法,代码不能编译

3.异常处理方式

Python中处理异常的方式有两种:捕获和抛出

学习:处理的语句的使用

3.1try-except-else

语法:

try:

​ 语句

except 错误表示码 as 变量:

​ 语句1

。。。。

else:

​ 语句2

说明:

​ a.try代码块被称为监控区域,检测其中的代码是否存在异常

​ b.当try中的代码没有异常,则except代码块没有执行的机会

​ c.当try中代码存在异常,则代码会停止在出现异常的地方,执行对应的except代码块

​ d.else语句可有可无,根据需求决定

​ e.注意:except代码块并不是真正意义上解决异常,而是将异常屏蔽掉

#1.使用except带有异常类型
"""
try:
    num = int(input("请输入一个数字:"))
    print(6 / num)

    print("hello")
except ZeroDivisionError as e:   #e只是一个变量,当前出现的异常的对象
    print(e)          #在异常类的内部,重写了str函数,返回当前异常的信息描述
    print(type(e))

print("over")


#2.一个try后面可以跟多个except
#工作原理:如果出现异常,在except语句中从上往下依次进行匹配,用法类似于if语句 的多分支
try:
    num = int(input("请输入一个数字:"))
    print(6 / num)

    print("hello")
except ZeroDivisionError as e:   #e只是一个变量,当前出现的异常的对象
    print(e)          #在异常类的内部,重写了str函数,返回当前异常的信息描述
    print(type(e))
except ValueError as e:
    print("value",e)
except TypeError as e:
    print(e)
except NameError as e:
    print(e)
print("over")
"""

#3.简写except:后面具体的错误类型
#工作原理:能够匹配所有的异常
"""
try:
    num = int(input("请输入一个数字:"))
    print(6 / num)

    print("hello")
except:
    print("出现了异常")
"""

#4.简写except:给出指定选择
#工作原理:只能匹配元组中给定的异常
"""
try:
    num = int(input("请输入一个数字:"))
    print(6 / num)

    list1 = [2,43,4]
    for i in range(10):
        print(list1[i])

    print("hello")
except (ZeroDivisionError,ValueError,NameError,TypeError):
    print("出现了异常")
"""

#5.except使用父类
#工作原理:Python中的异常都有一个父类BaseException,BaseException有一个父类Exception
#体现了多态的应用
#except从上往下依次匹配,如果父类出现在前面,优先匹配父类
"""
try:
    num = int(input("请输入一个数字:"))
    print(6 / num)

    print("hello")
#多态【父类的引用指向子类的对象】
except Exception as e:    #e =
    print("exception~~~~~",e)
except BaseException as e:
    print("base~~~",e)
except ZeroDivisionError as e:
    print("zero~~~",e)
    print(type(e))
except ValueError as e:
    print("value~~~",e)
except TypeError as e:
    print("type~~~",e)
print("over")
"""

#6.else分支
#else的执行时机:只有当try中的代码没有异常的时候,else才有执行的机会
"""
try:
    num = int(input("请输入一个数字:"))
    print(6 / num)

    print("hello")
except ZeroDivisionError as e:
    print(e)
else:
    print("else")
"""


#7.如果代码出现异常,可以在当前的位置捕获异常,或者可以在当前代码所在函数的位置捕获异常
def func(s):
    return  23 / int(s)

def show():
    s = input("请输入一个数据:")
    try:
        print(func(s))
    except:
        print("出现了异常")

show()

3.2try-except-finally

finally表示定义清理行为,表示无论在何种情况下都会执行的行为

语法:

try:

​ 语句

except 错误表示码 as 变量:

​ 语句1

。。。。

else:

​ 语句2

说明:

​ a.不管try中的代码有没有异常,finally都会被执行

​ b.使用场景:关闭文件,关闭数据库等

#1.直接使用
"""
try:
    print(10 / 0)
except ZeroDivisionError as e:
    print(e)
finally:
    print("finally被执行了")
"""

#2.特殊情况:当try或者except代码块中出现return,则finally会被执行
#工作原理:在return结束函数之前final被执行
"""
正常情况下
    a。try中的代码出现异常:try---->except---->finally
    b。try中的代码没有异常:try----->finally
"""
"""
def show():
    try:
        list1 = [2,4,34,3]
        num = int(input("请输入一个数字:"))
        for i in range(num):
            print(list1[i])

        return

        print("hello~~~~")
    except IndexError as e:
        print(e)

    finally:
        print("finally被执行~~~~~")

show()
"""

#3.文件读写完成写法
try:
    path = r"b.txt"
    f = open(path, "r", encoding="utf-8")

    result = f.read()

except FileNotFoundError as e:
    print("文件路径错误")
except LookupError as e:
    print("编码格式错误")
except ValueError as e:
    print("文件提前关闭")

finally:
    #其中的操作基本都是收尾操作
    #在保证文件被打开的情况下才关闭
    try:
        if f:
            f.close()
    except BaseException as e:
        print(e)
3.3raise抛出

语法:raise 异常类(“异常信息描述”)

说明:一般用在自定义异常中

注意:raise唯一的参数指定了要抛出的异常,他必须是一个异常的实例【对象】

​ 【代码本身没有异常,抛出了一个异常】

使用场景:如果你只想知道代码中某个地方是否抛出一个异常,并不想处理它,就可以将其重新抛出,使用raise 异常对象实现

try:
    num = int(input("请输入一个数字:"))
    print(10 / num)       #异常取决于num的值
except ZeroDivisionError as e:
    print(e)


try:
    raise ZeroDivisionError("异常描述")   #肯定有异常
except ZeroDivisionError as e:
    print(e)

print("hello")
3.4assert断言

好处:对于可能存在异常,又不确定的情况下,方便查找问题

def func(num,divNum):

    #断言
    #在可能存在异常的代码执行之前预言,如果预言成功,则执行后面的代码;
    # 如果预言失败,则会出现AssertionError的异常,异常的信息描述自定义的
   # assert (divNum != 0),"divNum不能为0"
    if divNum == 0:
        raise ZeroDivisionError("divNum不能为0")

    return  num / divNum


print(func(12,0))

print("over")

4.嵌套异常

可以在try,except和finally中继续书写try-except,在finally中嵌套使用比较多

作用:提高代码的严谨性或者提高代码的健壮性

#需求:我打算去拉萨
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.自定义异常

当需要处理生活中的数据的时候,系统的异常满足不了需求,则需要自定义异常

实现方式:继承自系统的异常类,可以继承自Exception类或者BaseException类【自定义异常也需要使用系统的异常机制】

实现步骤:

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

​ b.书写构造函数,调用父类的构造函数

​ c.在构造函数中定义一个实例属性,用于保存异常信息描述

​ d.重写__str__函数,使用异常对象的时候可以直接得到异常的信息描述

​ e.可选:书写一个成员函数,用来处理自己的异常

class MyException(BaseException):
    def __init__(self,message):
        #调用父类的构造函数:为了使用系统的异常机制
        super(MyException,self).__init__()
        self.message = message

    def __str__(self):
        return self.message

    def handle(self):
        print("处理了异常")


#使用自定义异常
try:
    raise MyException("出现了异常")
except MyException as e:
    print(e)

    #解决异常
    e.handle()

你可能感兴趣的:(Day10)