CH11. 文件及IO操作
文件的概述及基本操作步骤
文件的概述
- 存储在计算机的存储设备中的一组数据序列就是文件
- 不同类型的文件通过后缀名进行区分
- 文本文件
- 由于编码格式不同,所占磁盘空间的字节数不同
- 二进制文件
- 没有统一的编码,文件直接由0或1组成,需要使用指定的软件才能打开
- 文本文件
文件的基本操作
- 打开文件
变量名=open(filename, mode, encoding)
- 操作文件
变量名.read()
变量名.write(s)
- 关闭文件
变量名.close()
文件的打开模式 | 模式说明 |
---|---|
r | 以只读模式打开,文件指针在文件的开头,如果文件不存在,程序抛异常 |
rb | 以只读模式打开二进制文件,如图片文件 |
w | 覆盖写模式,文件不存在则创建,文件存在则内容覆盖 |
wb | 覆盖写模式写入二进制数据,文件不存在则创建,文件存在则覆盖 |
a | 追加写模式,文件不存在则创建,文件存在则在文件最后追加内容 |
+ | 与w/r/a等一同使用,在原功能的基础上追加同时读写功能 |
读写方法 | 描述说明 |
---|---|
file.read(size) | 从文件中读取size个字符或字节,如果没有给定参数,则读取文件中的全部内容 |
file.readline(size) | 读取文件中的一行数据,如果给定参数,则为读取这一行中的size个字符或字节 |
file.readlines() | 从文件中读取所有内容,结果为列表类型 |
file.write(s) | 将字符串s写入文件 |
file.writelines(lst) | 将内容全部为字符串的列表lst写入文件 |
file.seek(offset) | 改变当前文件操作指针的位置,英文占一个字节,中文gbk编码占两个字节,utf-8编码占3个字节 |
def my_write():
file = open('test.txt', 'w', encoding='utf-8')
file.write('伟大中国梦\n')
file.close()
def my_read():
file = open('test.txt', 'r', encoding='utf-8')
s = file.read()
print(type(s), s)
file.close()
def my_write_add(s):
file = open('test.txt', 'a', encoding='utf-8')
file.write(s)
file.close()
def my_write_list(file, lst):
f = open(file, 'a', encoding='utf-8')
f.writelines(lst)
f.close()
if __name__ == '__main__':
my_write()
my_read()
my_write_add('北京欢迎你\n')
my_write_add('为你开天辟地\n')
lst = ['姓名\t', '年龄\t', '成绩\n', 'Folin\t', '18\t', '99\n']
my_write_list('test.txt', lst)
'''
<class 'str'> 伟大中国梦
'''
def my_read(filename):
file = open(filename, 'w+', encoding='utf-8')
file.write('Hello!')
file.seek(0) # 文件指针回到开始位置
s=file.read()
print(type(s), s)
if __name__ == '__main__':
my_read('test_read.txt')
'''
<class 'str'> Hello!
'''
# 拷贝图片
def my_copy(src, dst):
sf = open(src, 'rb')
df = open(dst, 'wb')
s = sf.read()
df.write(s)
# 后打开的文件先关闭,先打开的文件后关闭
df.close()
sf.close()
if __name__ == '__main__':
src_file = './baidu_logo.png'
dst_file = './baidu_logo_2.png'
my_copy(src_file, dst_file)
with语句
-
with语句:又称上下文管理器,在处理文件时,无论是否产生异常,都能保证with语句执行完毕后关闭已经打开的文件,这个过程是自动的,无需手动操作。
-
语法结构:
-
with open(…) as file:
pass
-
def write_file(fname):
with open(fname, 'a', encoding='utf-8') as file:
str = 'with语句:又称上下文管理器,在处理文件时,无论是否产生异常,都能保证with语句执行完毕后关闭已经打开的文件,这个过程是自动的,无需手动操作。'
file.write(str)
def read_file(fname):
with open(fname, 'r', encoding='utf-8') as file:
print(file.read())
def copy_file(src_fname, dst_fname):
with open(src_fname, 'r', encoding='utf-8') as file:
with open(dst_fname, 'w', encoding='utf-8') as file2:
file2.write(file.read())
if __name__ == '__main__':
filename = './with_test.txt'
dst_file = './with_test_dst.txt'
write_file(filename)
read_file(filename)
copy_file(filename, dst_file)
read_file(dst_file)
'''
with语句:又称上下文管理器,在处理文件时,无论是否产生异常,都能保证with语句执行完毕后关闭已经打开的文件,这个过程是自动的,无需手动操作。
with语句:又称上下文管理器,在处理文件时,无论是否产生异常,都能保证with语句执行完毕后关闭已经打开的文件,这个过程是自动的,无需手动操作。
'''
数据的组织维度及存储
- 数据的组织维度:也称为数据的组织方式或存储方式,在Python中常用的数据组织方式可分为一维数据、二维数据和高维数据
- 一维数据:通常采用线性方式组织数据,一般使用Python中的列表、元组或者集合进行存储数据
- 二维数据:二维数据也称表格数据,由行和列组成,类似于Excel表格,在Python中使用二维列表进行存储
- 高维数据:则是使用Key-Value方式进行组织数据,在Python中使用字典进行存储数据。在Python中内置的json模块专门用于处理JSON(JavaScript Object Notation)格式的数据
import json
lst = [
{'name':'张三', 'age':18, 'score':90},
{'name':'李四', 'age':19, 'score':99},
{'name':'王五', 'age':17, 'score':89}
]
# ensure_ascii正常显示中文,ident增加数据的缩进,美观
s = json.dumps(lst, ensure_ascii=False, indent=4)
print(type(s))
print(s)
# 解码
lst2 = json.loads(s)
print(type(lst2))
print(lst2)
# 编码到文件中
with open('student.txt', 'w') as file:
json.dump(lst,file,ensure_ascii=False, indent=4)
# 解码到程序
with open('student.txt', 'r') as file:
lst3 = json.load(file)
print(type(lst3))
print(lst3)
'''
<class 'str'>
[
{
"name": "张三",
"age": 18,
"score": 90
},
{
"name": "李四",
"age": 19,
"score": 99
},
{
"name": "王五",
"age": 17,
"score": 89
}
]
<class 'list'>
[{'name': '张三', 'age': 18, 'score': 90}, {'name': '李四', 'age': 19, 'score': 99}, {'name': '王五', 'age': 17, 'score': 89}]
<class 'list'>
[{'name': '张三', 'age': 18, 'score': 90}, {'name': '李四', 'age': 19, 'score': 99}, {'name': '王五', 'age': 17, 'score': 89}]
'''
目录与文件的相关操作
os
:Python内置的与操作系统文件显像管的模块,该模块中语句的执行结果通常与操作系统有关,即有些函数的运行效果在Windows操作系统和MacOS系统中不一样
函数名称 | 描述 |
---|---|
getcwd() | 获取当前的工作路径 |
listdir(path) | 获取path路径下的文件和目录信息,如果没有指定path,则获取当前路径下的文件和目录信息 |
mkdir(path) | 在指定路径下创建目录(文件夹) |
makedirs(path) | 创建多级目录 |
rmdir(path) | 删除path下的空目录 |
removedirs(path) | 删除多级目录 |
chdir(path) | 把path设置为当前目录 |
walk(path) | 遍历目录树,结果为元组,包含所有路径名、所有目录列表和文件列表 |
remove(path) | 删除path指定的文件 |
rename(old,new) | 将old重命名为new |
stat(path) | 获取path指定的文件信息 |
startfile(path) | 启动path指定的文件 |
os.path模块
- 是os模块的子模块,也提供了一些目录或文件的操作函数
函数名称 | 描述 |
---|---|
abspath(path) | 获取目录或文件的绝对路径 |
exists(path) | 判断目录或文件在磁盘上是否存在,结果为bool类型,如果目录或文件在磁盘上存在,结果为True,否则为False |
join(path,name) | 将目录与目录名或文件名进行拼接,相当于字符串的“+”操作 |
splitext() | 分别获取文件名和后缀名 |
basename(path) | 从path中提取文件名 |
dirname(path) | 从path中提取路径(不包含文件名) |
isdir(path) | 判断path是否是有效路径 |
isfile(path) | 判断file是否是有效文件 |
实战
实战1
-
批量创建文件
-
在指定路径下批量创建3000份文本文件,文件名格式为
序号_物资类别_用户识别码
组成1) 序号从0001到3000
2)物资类别包括:水果、烟酒、粮油、肉蛋、蔬菜
3)用户识别码为9位的随机十六进制数码
-
import os
import os.path
import random
# 函数式编程
def creat_filename():
filename_lst = []
lst = ["水果", "烟酒","粮油", "肉蛋", "蔬菜"]
code = ['0', '1', '2','3','4','5','6','7','8','9','A','B','C','D','E','F']
for i in range(1, 101):
filename = ''
num = '{0:0>4}'.format(str(i)) # 格式化
filename += num # 序号
filename += '_'
filename += random.choice(lst) # 类别
filename += '_'
s = ''
for item in range(9):
s += random.choice(code)
filename += s # 识别码
filename_lst.append(filename)
return filename_lst
def cread_file(filename):
with open(filename, 'w') as file:
pass
if __name__ == '__main__':
filename_lst = creat_filename()
cur_path = os.getcwd()
data_path = cur_path + '/data'
if not os.path.exists(data_path):
os.mkdir(data_path)
for item in filename_lst:
cread_file(os.path.join(data_path, item) + '.txt')
实战2
- 批量创建文件夹
- 在指定路径newdir下批量创建指定个数的目录(文件夹),如果newdir目录不存在,则创建
import os
import os.path
def mkdirs(path, num):
if not os.path.exists(path):
os.mkdir(path)
for i in range(1, num+1):
dst_dir = os.path.join(path, str(i))
if not os.path.exists(dst_dir):
os.mkdir(dst_dir)
if __name__ == '__main__':
new_dir = './newdir'
mkdirs(new_dir, 10)
实战3
- 记录用户登录日志并查看
- 创建XX客服管理系统的登录界面,每次登录时,将用户的登录日志写入文件中,并且可以在程序中查看用户的登录日志
import os
import os.path
import time
def show_info():
print('输入提示数字,执行相应的操作:0-退出,1-查看登录日志')
# 记录日志
def write_login_log(username):
with open('log.txt', 'a', encoding='utf-8') as file:
s = f'用户名:{username}, 登录时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))}\n'
file.write(s)
# 读取日志
def read_login_log():
with open('log.txt', 'r', encoding='utf-8') as file:
while True:
line = file.readline()
if line == '':
break
else:
print(line)
if __name__ == '__main__':
username = input("请输入用户名:")
password = input("请输入密码:")
if username == 'admin' and password == 'admin':
print('登陆成功')
write_login_log(username)
show_info()
num = eval(input("请输入要操作的数字:"))
while True:
if num == 0:
print('退出成功')
break
elif num == 1:
print('查看登录日志')
read_login_log()
else:
print('对不起,您输入的数字有误')
# 下一次循环需要继续提示
show_info()
num = eval(input("请输入要操作的数字:"))
else:
print('用户名或密码不正确')
实战4
- 模拟淘宝客服自动回复
- 需求:淘宝客服为了快速回答买家的问题,设置了自动回复的功能,当有买家咨询时,客服自助系统会首先使用提前规划好的内容进行回复,请用Python程序实现这一功能
import os
def find_answer(question):
with open('replay.txt', encoding='utf-8') as file:
while True:
line = file.readline()
if line == '':
break
else:
keyword = line.split('|')[0]
reply = line.split('|')[1]
if keyword in question:
return reply
return False
if __name__ == '__main__':
question = input("Hi, XXX你好,有什么烦恼和小蜜说说吧:")
while True:
if question == 'bye':
break
else:
reply = find_answer(question)
if reply == False:
question = input('小蜜不知道您在说什么,您可以问我一些关于订单、物流、账户和支付方面的问题,退出请说bye:')
else:
print(reply)
question = input('小主,您还可以问我一些关于订单、物流、账户和支付方面的问题,退出请说bye:')
print('小主再见!')