1 异常
错误:语法错误(一般IDE能够发现),逻辑错误(很难发现,提示起来比较麻烦)
异常:当python检测到一个错误时,解释器无法继续执行下去,于是抛出相应的信息,这些信息称为异常
程序抛出异常的情况:
- 系统自己抛出异常,如除法操作时除数为0
- 程序主动抛出异常,代码中使用
raise
语句
1.1 异常处理
python中异常处理的常见结构
try:# 执行代码
except:# 发生异常时执行的代码
else:# 没有异常时执行的代码
finally:# 不管有没有异常都会执行的代码
其中else
与finally
为非必需操作
代码示例
try:print('-----test--1---')open('123.txt','r')print('-----test--2---')
except IOError: pass
finally:print('finally')
IOError是指抛出了IO错误,python中有很多描述和处理异常的类,我们称之为异常类,异常类中定了包含该类异常的信息和对异常进行处理的方法,其中BaseException
是所有异常的父类。
except
捕获多个异常的情况
a = input("请输入分子:")
b = input("请输入分母:")
try:print('a/b的结果为:', int(a)/int(b))
except ZeroDivisionError as e:print(e) # 打印异常信息print("除数不能为0")
except ValueError:print("请输入数字")
except: # 捕获其他未指定的异常print("其他异常")c = input("请输入分子:")
d = input("请输入分母:")
try:print('a/b的结果为:', int(a)/int(b))
except (ZeroDivisionError, ValueError): # 同时捕获多个异常print("除数不能为0或请输入数字")
except: # 捕获其他未指定的异常print("其他异常")
raise
抛出异常
def div(a, b):if b == 0:raise Exception("除数不能为0")else:return a / btry:result = div(10, 0)print(result)
except Exception as e:print("发生异常:", e)
assert的使用
assert
:断言,不满足断言,会抛出错误AssertionError
;当程序运行到某一个节点的时候,就会断定
def div(a, b):assert b > 0return a / bresult = div(10, 0)# 输出
'''File "C:\Users\maple\Desktop\python\1.py", line 5, in <module>result = div(10, 0)^^^^^^^^^^File "C:\Users\maple\Desktop\python\1.py", line 2, in divassert b > 0
AssertionError
'''
1.2 自定义异常
class ShortInputException(Exception):def __init__(self, length, atleast):# super().__init__()self.length = lengthself.atleast = atleast
try:s = input('请输⼊ --> ')print(s)if len(s) < 3:# raise引发⼀个你定义的异常raise ShortInputException(len(s), 3)
except ShortInputException as result:#x这个变量被绑定到了错误的实例print('ShortInputException: 输⼊的⻓度是 %d,⻓度⾄少应是 %d'%(result.length, result.atleast))
else:print('没有异常发⽣.')
2 文件和流
根据文件中数据的组织形式,把文件分为以下的两类
- 文本文件:存储普通“字符”文本,python默认为unicode字符集(两个字节表示一个字符,最多可以表示 65536个),可以使用记事本程序打开。
- 二进制文件:把数据内容用“字节存储”,无法使用记事本打开,必须使用专用的解码软件。常见的格式有MP4、MP3、Word等
2.1 文件与文件夹操作
# f = open('test.txt', 'wra') # 这种方式会报错 w r a 只能拥有一个 当需要读写模式同时存在,可以使用 a+ w+ r+ 的模式
f = open('test.txt', 'r+')
content = f.read(5) #读取前5个字符
print(content)
f.seek(0) # 由于read直接读到了 文件中间某个位置 我们需要使用seek将指针跳至最前面
f.read() # 读取所有内容 有\n符
f.seek(0)
f.readlines() # 读取所有内容,返回一个list,每个元素为每一行 包含换行符
f.write('yes') # 向文件中写入内容
position = f.tell() # 通过tell函数来获取目前光标开始的位置
f.seek(5, 0) # 移动光标指针位置
open(file[,mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None])
file
参数是必须的,指定需要打开的文件名,使用相对路径或者绝对路径都可以
mode
参数用于指定文件模式,如只读、写入、追加等,具体如下表;
encoding
用于指定编码读取文件,常见编码方式 UTF-8, unicode, GB2312, ISO8859-1等,具体大家可以查询相关的资料
文件模式 | 描述 |
---|---|
r | 读模式(默认) |
w | 写模式(原文件存在会覆盖原文件) |
a | 追加模式(原文件存在是在原文件之后追加内容) |
b | 二进制模式(可与其他模式一起存在) |
x | 排他的写模式(只能自己写) |
t | 文本模式,默认值 |
+ | 读写模式(必须与其他文件模式一起使用) r+(文件读写,文件存在,从当前位置开始追加内容,不存在则报错);w+(文件读写,文件存在则清空文件写入新内容,不存在则创建文件),a+(文件不存在则创建新文件,文件存在则指针跳到文件尾部,使用这种方式读取文件内容的时候,需要使用seek(0) 跳入文件首部才可以读取文件) |
open(filename, mode)
函数用于打开一个文件,并返回文件对象f
,文件对象常用的函数如下
方法 | 描述 |
---|---|
close() | 关闭文件,关闭文件之后不能再进行读写 |
flush() | 刷新文件内部缓存,直接把内部缓存区的数据立刻写入文件,而不是被动的等待输出缓冲区写入 |
fileno() | 返回一个整型的文件描述符,可以用在如os模块的read方法等一些底层操作上 |
isatty() | 如果一个文件连接到一个终端设备返回True,否则返回False |
next() | 返回文件的下一行 |
read(size) | 从文件读取size大小的字节数,如果未指定或为负数则读取所有 |
readline() | 读取整行,包括\n 换行符 |
seek(offset) | 设置文件当前位置 |
tell() | 返回文件当前位置 |
truncate() | 截取文件,截取的字节通过size指定,默认为当前文件位置 |
write(str) | 将字符串str写入文件,没有返回值 |
writelines(squence) | 向文件写入一个序列字符串列表,如果需要换行需要自己加入每行的换行符 |
以上的示例还可以通过 with 包裹 如下 |
with open('test.txt', 'r+') as f:content = f.read(5) #读取前5个字符print(content)f.seek(0) # 由于read直接读到了 文件尾部 我们需要使用seek将指针跳至最前面print(f.read()) # 读取所有内容 有\n符`f.seek(0) # 由于read直接读到了 文件尾部 我们需要使用seek将指针跳至最前面print(f.readlines()) # 读取所有内容,返回一个list,每个元素为每一行 包含换行符f.write('yes') # 向文件中写入内容position = f.tell() # 通过tell函数来获取目前光标开始的位置# f.seek(5, 0) # 移动光标指针位置f.close()
2.2 seek函数讲解
f.seek(p, 0)
或 f.seek(p)
将文件读取指针移动到文件的第p个字节处,表示绝对位置。f.seek(0)移动到文件头位置。
f.seek(p, 1)
在当前位置的基础上,将文件读取指针移动p个字节,表示相对位置。
f.seek(p, 2)
在文件尾的基础上,将文件读取指针移动p个字节,表示相对位置。f.seek(0, 2)移动到文件尾位置。
2.3 StringIO 与 BytesIO
有时候,数据读写不是对文件进行操作,也可以从内存(变量)中进行读写。 我们可以使用 StringIO
和 BytesIO
from io import StringIO, BytesIOs = StringIO()
s.write("1")
s.write(" ")
s.write("2")print(s.getvalue()) # getvalue方法 获取写入后的 字符 s2 = StringIO("hello \n maple")
while True:s = s2.readline()if s == "":breakprint(s.strip())f = BytesIO()
f.write("i love it".encode("utf-8"))
print(f.getvalue())f2 = BytesIO(b'\xe4\xbd\xa0\xe7\x88\xb1')
print(f2.read().decode("utf-8"))
2.4 文件重命名
import os
os.rename('1.txt', '2.txt')
2.5 文件删除
import os
os.remove('1.txt')
2.6 文件复制(shutil模块)
shutil
模块是对os模块的补充,提供了移动、复制等操作
一般复制操作用的比较多
import shutil
shutil.copyfile("1.txt", "1_copy.txt") # 复制文件
shutil.copytree("a/b", "c", ignore=shutil.ignore_patterns("*.html", "*.css")) # 当 c 文件夹不存在时才可以使用 用于复制文件夹,忽略 html 与 css 文件
2.7 文件夹操作
import os
- 创建文件夹
os.mkdir(dir_name)
- 删除文件夹
os.removedirs(dir_name)
- 获取当前目录
os.getcwd()
- 获取目录列表
os.listdir(dir_name)
- 改变当前工作目录
os.chdir(dir_name)
还有其他很多操作函数,这里就不一一列举,大家可以通过搜索(搜索引擎与大模型都可)查询相关使用