Python学习笔记系列之013:文件操作

 

一、文件的打开与关闭

1. 文件的打开

在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件。

open(文件名,访问模式)

示例如下:
f = open('test.txt', 'w')

2. 文件的关闭

示例如下:

# 新建一个文件,文件名为:test.txt
f = open('test.txt', 'w')

# 关闭这个文件
f.close()

注意:文件打开,执行必要的操作后必须要关闭。

但是我们总是经常忘记关闭它,怎么办呢?

3. 文件的另一种打开方式

with open(文件名, 访问模式) as 别名:
    pass  # 对文件执行的操作

上述方法和以下代码是等价的:

别名 = open(文件名, 访问模式)
pass
别名.close()

由此可知,使用with方法访问文件,就不必在手动close它,Python会自动把文件关闭掉,是不是很贴心?

二、文件的读写

1. 写数据(write)

使用write()可以完成向文件写入数据。
demo:

# 新建一个文件 file_write_test.py,向其中写入如下代码:
f = open('test.txt', 'w')
f.write('hello world, i am here!')
f.close()
# 运行之后会在file_write_test.py文件所在的路径中创建一个文件test.txt,其中数据如下:
hello world, i am here!

注意:
如果文件不存在那么创建,如果存在那么就先清空,然后写入数据。

2. 读数据(read)

使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。
num大于数据长度时,不会报错。读完后,再读的话,会得到''空字符串。
demo:

# 新建一个文件file_read_test.py,向其中写入如下代码:
f = open('test.txt', 'r')
content = f.read(5) # 最多读取5个数据
print(content)
print("-"*30) # 分割线,用来测试
content = f.read() # 从上次读取的位置继续读取剩下的所有的数据
print(content)
f.close() # 关闭文件,这个是个好习惯哦

# 运行现象:
hello
------------------------------
world, i am here!

注意:
如果用open打开文件时,如果使用的"r",那么可以省略,即只写 open('test.txt')

3. 读数据(readlines)

就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
读完后,再读的话,会得到[]空列表。

demo:

#coding=utf-8
f = open('test.txt', 'r')
content = f.readlines()
print(type(content))

i=1
for temp in content:
    print("%d:%s" % (i, temp))
    i += 1

f.close()

运行现象:
<class 'list'>
1:hello world, i am here!

<4>读数据(readline)

一次读一行。读完后,再读的话,会得到''空字符串。

#coding=utf-8
f = open('test.txt', 'r')

content = f.readline()
print("1:%s" % content)

content = f.readline()
print("2:%s" % content)

f.close()

运行现象:
1:hello world, i am here!
2:hello world, i am here!

想一想:
如果一个文件很大,比如5G,试想应该怎样把文件的数据读取到内存然后进行处理呢?

案例:制作文件的备份

任务描述:输入文件的名字,然后程序自动完成对文件进行备份。

参考代码:

# 获取文件名
src_name = input('请输入要备份的文件名:')

# 漂亮的目标文件名 aaa.bbb.txt
index = src_name.rfind('.')
dest_name = src_name[:index]+'[复件]' + src_name[index:]

# 打开文件
src_file = open(src_name, 'rb')
dest_file = open(dest_name, 'wb')

# 复制文件内容
while True:
    content = src_file.read(1024*8)   # 1024表示1024个字节
    if len(content) == 0:
        break

dest_file.write(content)

# 关闭文件
src_file.close()
dest_file.close()

为什么使用src_file.read(1024*8),而不是src_file.read()呢?因为如果文件很大的话,使用read()读取会把内存撑爆。这时候使用以1024字节单位循环读取的话,就可以读取大文件了。

三、文件的相关操作

有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能。
1. 文件重命名

os模块中的rename()可以完成对文件的重命名操作。
rename(需要修改的文件名, 新的文件名)
import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")

2. 删除文件
os模块中的remove()可以完成对文件的删除操作。
remove(待删除的文件名)
import os
os.remove("毕业论文.txt")

3. 创建文件夹
import os
os.mkdir("张三")

4. 删除文件夹
import os
os.rmdir("张三")

5. 获取当前目录
import os
os.getcwd()

6. 改变默认目录
import os
os.chdir("../")

7. 获取目录列表
import os
os.listdir("./")

案例:批量修改文件名

需求:批量在文件名前加前缀

参考代码:

#coding=utf-8
# 批量在文件名前加前缀
import os
funFlag = 1 # 1表示添加标志 2表示删除标志
folderName = './renameDir/'

# 获取指定路径的所有文件名字
dirList = os.listdir(folderName)

# 遍历输出所有文件名字
for name in dirList:
    print(name)

    if funFlag == 1:
        newName = '[孟德出品]-' + name
    elif funFlag == 2:
        num = len('[孟德出品]-')
        newName = name[num:]
print(newName)

os.rename(folderName+name, folderName+newName)
View Code

四、编码转换

str->bytes:encode编码
bytes->str:decode解码
字符串通过编码成为字节码,字节码通过解码成为字符串。

>>> text = '我是文本'
>>> text
'我是文本'
>>> print(text)
我是文本
>>> bytesText = text.encode()
>>> bytesText
b'\xe6\x88\x91\xe6\x98\xaf\xe6\x96\x87\xe6\x9c\xac'
>>> print(bytesText)
b'\xe6\x88\x91\xe6\x98\xaf\xe6\x96\x87\xe6\x9c\xac'
>>> type(text)
<class 'str'>
>>> type(bytesText)
<class 'bytes'>
>>> textDecode = bytesText.decode()
>>> textDecode
'我是文本'
>>> print(textDecode)
我是文本

其中decode()与encode()方法可以接受参数,其声明分别为:

bytes.decode(encoding="utf-8", errors="strict")
str.encode(encoding="utf-8", errors="strict")

其中的encoding是指在解码编码过程中使用的编码(此处指“编码方案”是名词),errors是指错误的处理方案。
errors有两个选项:

strict 表示严格按照指定的格式进行编码解码,如果编码解码不成功,则程序崩溃。
ignore 表示忽略编码解码不成功的字符,这样代码不会崩溃。

详细的可以参照官方文档:
str.encode()
bytes.decode()

五、综合应用:学生管理系统 (文件版)

 需求就不说了,先把代码运行一遍,看看效果,然后自己写一个。

  1 import time
  2 import os
  3  
  4 # 定一个列表,用来存储所有的学生信息(每个学生是一个字典)
  5 info_list = []
  6  
  7  
  8 def print_menu():
  9     print("---------------------------")
 10     print("      学生管理系统 V1.0")
 11     print(" 1:添加学生")
 12     print(" 2:删除学生")
 13     print(" 3:修改学生")
 14     print(" 4:查询学生")
 15     print(" 5:显示所有学生")
 16     print(" 6:保存数据")
 17     print(" 7:退出系统")
 18     print("---------------------------")
 19  
 20  
 21 def add_new_info():
 22     """添加学生信息"""
 23     global info_list
 24  
 25     new_name = input("请输入姓名:")
 26     new_tel = input("请输入手机号:")
 27     new_qq = input("请输入QQ:")
 28  
 29     for temp_info in info_list:
 30         if temp_info['name'] == new_name:
 31             print("此用户名已经被占用,请重新输入")
 32             return  # 如果一个函数只有return就相当于让函数结束,没有返回值
 33  
 34     # 定义一个字典,用来存储用户的学生信息(这是一个字典)
 35     info = {}
 36  
 37     # 向字典中添加数据
 38     info["name"] = new_name
 39     info["tel"] = new_tel
 40     info["qq"] = new_qq
 41  
 42     # 向列表中添加这个字典
 43     info_list.append(info)
 44  
 45  
 46 def del_info():
 47     """删除学生信息"""
 48     global info_list
 49  
 50     del_num = int(input("请输入要删除的序号:"))
 51     if 0 <= del_num < len(info_list):
 52         del_flag = input("你确定要删除么?yes or no")
 53         if del_flag == "yes":
 54             del info_list[del_num]
 55     else:
 56         print("输入序号有误,请重新输入")
 57  
 58  
 59 def modify_info():
 60     """修改学生信息"""
 61     global info_list
 62  
 63     modify_num = int(input("请输入要修改的序号:"))
 64     if 0 <= modify_num < len(info_list):
 65         print("你要修改的信息是:")
 66         print("name:%s, tel:%s, QQ:%s" % (info_list[modify_num]['name'],
 67             info_list[modify_num]['tel'],info_list[modify_num]['qq']))
 68         info_list[modify_num]['name'] = input("请输入新的姓名:")
 69         info_list[modify_num]['tel'] = input("请输入新的手机号:")
 70         info_list[modify_num]['qq'] = input("请输入新QQ:")
 71     else:
 72         print("输入序号有误,请重新输入")
 73  
 74  
 75 def search_info():
 76     """查询学生信息"""
 77     search_name = input("请输入要查询的学生姓名:")
 78     for temp_info in info_list:
 79         if temp_info['name'] == search_name:
 80             print("查询到的信息如下:")
 81             print("name:%s, tel:%s, QQ:%s" % (temp_info['name'],
 82                 temp_info['tel'], temp_info['qq']))
 83             break
 84     else:
 85         print("没有您要找的信息....")
 86  
 87  
 88 def print_all_info():
 89     """遍历学生信息"""
 90     print("序号\t姓名\t\t手机号\t\tQQ")
 91     i = 0
 92     for temp in info_list:
 93         # temp是一个字典
 94         print("%d\t%s\t\t%s\t\t%s" % (i, temp['name'], temp['tel'], temp['qq']))
 95         i += 1
 96  
 97  
 98 def save_data():
 99     """加载之前存储的数据"""
100     f = open("info_data.data", "w")
101     f.write(str(info_list))
102     f.close()
103  
104  
105 def load_data():
106     """加载之前存储的数据"""
107     global info_list
108     f = open("info_data.data")
109     content = f.read()
110     info_list = eval(content)
111     f.close()
112  
113 def main():
114     """用来控制整个流程"""
115  
116     # 加载数据(1次即可)
117     load_data()
118  
119     while True:
120         # 1. 打印功能
121         print_menu()
122  
123         # 2. 获取用户的选择
124         num = input("请输入要进行的操作(数字):")
125  
126         # 3. 根据用户选择,做相应的事情
127         if num == "1":
128             # 添加学生
129             add_new_info()
130         elif num == "2":
131             # 删除学生
132             del_info()
133         elif num == "3":
134             # 修改学生
135             modify_info()
136         elif num == "4":
137             # 查询学生
138             search_info()
139         elif num == "5":
140             # 遍历所有的信息
141             print_all_info()
142         elif num == "6":
143             # 保存数据到文件中
144             save_data()
145         elif num == "7":
146             # 退出系统
147             exit_flag = input("亲,你确定要退出么?~~~~(>_<)~~~~(yes or no) ")
148             if exit_flag == "yes":
149                 break
150         else:
151             print("输入有误,请重新输入......")
152  
153  
154         input("\n\n\n按回车键继续....")
155         os.system("clear")  # 调用Linux命令clear完成清屏
156  
157 # 程序的开始
158 main()
159  
160 注意:
161 以上程序,在运行之前请先建立info_data.data文件,并且写入一对中括号[]即可
162 等到后面讲解完异常之后就解决了这个问题
163  
View Code

猜你喜欢

转载自www.cnblogs.com/salmond/p/8926054.html