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
装饰器实现单例问题补充:
#方式一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:Comma Separated Values,逗号分隔值
.csv文件类似于.txt文件,是一种特殊的纯文本的文件格式
特点:字符之间使用逗号或者tab键隔开,主要不同程序之间进行数据的交互
注意:在Windows下可以使用excel,文本文档,notepad++,subline等打开
用法:需要导入模块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)
#第一步:导入模块 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))
Python中有两种错误很容易辨认:语法错误【解析错误】和异常
语法错误:在pycharm中,立即报错
异常:代码正常,运行之后才会出错
异常:一种可能性
异常处理:只是将可能性考虑到,将错误屏蔽掉,保证后面的代码正常执行
num = 10 print(num) #特点:一旦程序中出现异常,并且该异常未被处理,则代码将停止,后面的代码没有执行的机会 #需要解决的问题:当程序遇到异常时,不让程序结束,接着向下执行 print(num / 0) print("over")
AttributeError:一个对象试图访问了一个不存在的属性或者方法
IOError:输入/输出异常,读写文件的过程中基本上无法打开文件
ImportError:导入模块的时候异常;基本上是路径或者名称错误
IndexError:列表或者元组或者字符串的下标越界
KeyError:试图访问不存在的key
ValueError:传入一个不期望的值
TypeError:传入的数据类型不匹配
NameError:使用了一个未被定义的变量
UnboundLocalError:使用了还未被定义的局部变量:基本上由于存在另外一个同名的全局变量,你正在访问的时候【nonlocal global】
SyntaxError;代码非法,代码不能编译
Python中处理异常的方式有两种:捕获和抛出
学习:处理的语句的使用
语法:
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()
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)
语法: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")
好处:对于可能存在异常,又不确定的情况下,方便查找问题
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")
可以在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("到拉萨了,拉萨真漂亮")
当需要处理生活中的数据的时候,系统的异常满足不了需求,则需要自定义异常
实现方式:继承自系统的异常类,可以继承自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()