一、文件操作的基本流程
- open( )
open( ) 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
open(file, mode, encoding)
- mode 中常用的参数
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
- 实例(Python 3.0+)
#!-*- coding:utf-8 -*-
f_read = open("test", "r" ,encoding = "utf-8")
f_content = f_read.read()
f_read.close()
print(f_content)
二、几个常用的方法
1、read( )
read() 方法用于从文件读取指定的字节数,如果未给定或为负则读取所有。
read(self, n)
2、readline( )
readline( ) 方法用于从文件读取整行,包括 “\n” 字符。如果指定了一个非负数的参数,则返回指定大小的字节数,包括 “\n” 字符。
readline(self, limit)
3、readlines( )
readlines( ) 方法用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for… in … 结构进行处理。 如果碰到结束符 EOF 则返回空字符串。
readlines(self, args, kwargs)
4、write( )
write( ) 方法用于向文件中写入指定字符串。
在文件关闭前或缓冲区刷新前,字符串内容存储在缓冲区中,这时你在文件中是看不到写入的内容的。
如果文件打开模式带 b,那写入文件内容时,str (参数)要用 encode 方法转为 bytes 形式,否则报错:TypeError: a bytes-like object is required, not ‘str’。
write(self, s)
5、close( )
close( ) 方法用于关闭一个已打开的文件。关闭后的文件不能再进行读写操作, 否则会触发 ValueError 错误。 close( ) 方法允许调用多次。
当 file 对象,被引用到操作另外一个文件时,Python 会自动关闭之前的 file 对象。 使用 close( ) 方法关闭文件是一个好的习惯。
close( )
6、flush( )
flush( ) 方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。
一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush( ) 方法。
flush(self)
7、fileno( )
fileno( ) 方法返回一个整型的文件描述符(file descriptor FD 整型),可用于底层操作系统的 I/O 操作。
fileno(self)
8、tell( )
tell( ) 方法返回文件的当前位置,即文件指针当前位置。
tell(self)
9、seek( )
seek( ) 方法用于移动文件读取指针到指定位置。
seek(self, offset, whence)
10、isatty( )
isatty( ) 方法检测文件是否连接到一个终端设备,如果是返回 True,否则返回 False。
isatty(self)
11、truncate( )
truncate( ) 方法用于从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除。
truncate(self, size)
- 实例(Python 3.0+)
#!-*- coding:utf-8 -*-
f_read = open("test", "r+", encoding = "utf-8")
f_fileno = f_read.fileno()
f_content = f_read.readline(5)
f_tell = f_read.tell() # 一个字符占三个字节
f_read.seek(18)
f_tell2 = f_read.tell()
f_content2 = f_read.readline(4)
f_read.close()
print("文件描述符为 :", f_fileno)
print("读取内容为 :", f_content)
print("当前指针位置 :", f_tell)
print("移动后指针位置 :", f_tell2)
print("指针移动后读取内容为 :", f_content2)
- test 中内容
帘外雨潺潺,春意阑珊。
罗衾不耐五更寒。
梦里不知身是客,一晌贪欢。
独自莫凭栏,无限江山,别时容易见时难。
流水落花春去也,天上人间。
三、修改磁盘文件
由于文件读写的特性,无法对原文件中的某一部分内容进行修改,所以只能先读取文件内容,对内容进行修改后再写入新的文件以完成修改。
#!-*- coding:utf-8 -*-
f_read = open("test", "r" ,encoding = "utf-8")
f_write = open("test2", "w" ,encoding = "utf-8")
num = 0
for line in f_read:
num += 1
if num == 2:
line = "pass\n"
f_write.write(line)
f_read.close()
f_write.close()
四、可添加版三级菜单(Python 3.0+)
#!-*- coding:utf-8 -*-
# author : Springer
# localInfo 代码下方已给,localInfo_temp 是为修改文件而设置的临时文件,其内容为空。
# 定义一个遍历来显示需要展示的内容
def show_all(show_num, user_pro, user_cit):
f_read = open("localInfo", "r", encoding="utf-8")
dic_all = f_read.read()
f_read.close()
dic_all = eval(dic_all)
index = 1
if show_num == 1: # 显示省级
for i in dic_all:
print(index, "\t", i)
index += 1
elif show_num == 2: # 显示市级
for j in dic_all[num_province(user_pro)]:
print(index, "\t", j)
index += 1
elif show_num == 3: # 显示县级
count = len(dic_all[num_province(user_pro)][num_city(user_pro, user_cit)])
list_temp = dic_all[num_province(user_pro)][num_city(user_pro, user_cit)].copy()
for z in range(count):
print(index, "\t", list_temp[z])
index += 1
# 将用户输入的数字转换为对应的地点
def num_address(num_prov, num_cit, num_coun,choose):
f_read = open("localInfo", "r", encoding="utf-8")
dic_all = f_read.read()
f_read.close()
dic_all = eval(dic_all)
str_address = ""
index = 1
if choose == 1: # 省级转换
for i in dic_all:
if index == num_prov:
return i # 返回需要的值
index += 1
elif choose == 2: # 市级转换
for j in dic_all[num_province(num_prov)]:
if index == num_cit:
return j # 返回需要的值
index += 1
elif choose == 3: # 县级转换
for z in range(len( dic_all[num_province(num_prov)][num_city(num_prov,num_cit)])):
if index == num_coun and choose == 3:
str_address = dic_all[num_province(num_prov)][num_city(num_prov,num_cit)][z]
return str_address # 返回需要的值
index += 1
else:
print("Error !")
return str_address # 返回需要的值
# 调用转换函数得到省级名称
def num_province(num_pro):
str_province = num_address(num_pro, 0, 0, 1)
return str_province
# 调用转换函数得到市级名称
def num_city(num_pro, num_cit):
str_city = num_address(num_pro, num_cit, 0, 2)
return str_city
# 调用转换函数得到县级名称
def num_country(num_pro, num_cit, num_cou):
str_country = num_address(num_pro, num_cit, num_cou, 3)
return str_country
# 获取字典中省、市、县的数量,用来判断用户输入是否符合条件
def count_num(pro, con, flag):
f_read = open("localInfo", "r", encoding="utf-8")
dic_all = f_read.read()
f_read.close()
dic_all = eval(dic_all)
if flag == 1:
_index_province = len(list(dic_all.keys()))
return _index_province
elif flag == 2:
_index_city = len( list(dic_all[num_province(pro)].keys()))
return _index_city
elif flag == 3:
_index_country = len( dic_all[num_province(pro)][num_city(pro,con)])
return _index_country
# 让用户自行添加地点
def user_add(user_local_pro, user_local_cit, user_local_coun, save_flag):
temp_flag = 0
write_flag = 0
with open("localInfo", "r", encoding="utf-8") as f_read, \
open("localInfo_temp", "w", encoding="utf-8") as f_write:
for line in f_read: # 将用户输入的信息保存到临时文件中
write_flag += 1
if save_flag == 1 and write_flag == 1:
line = "".join(
["{\n\t'", user_local_pro, "':\n\t\t{\n\t\t'", user_local_cit,
"':\n\t\t\t['", user_local_coun,"']\n\t\t},\n"])
elif save_flag == 2 and line.strip() == "".join(["'", user_local_pro, "':"]):
temp_flag = write_flag + 1
elif save_flag == 2 and write_flag == temp_flag:
line = "".join(["\t\t{\n\t\t'", user_local_cit, "':\n\t\t\t[\n\t\t\t'(custom)'],\n"])
elif save_flag == 3 and line.strip() == "".join(["'", user_local_cit, "':"]):
temp_flag = write_flag + 2
elif save_flag == 3 and write_flag == temp_flag:
line = "".join(["\t\t\t'", user_local_coun, "',", line.strip(), "\n"])
f_write.write(line)
# 保存用户添加的信息
def user_save():
with open("localInfo_temp", "r", encoding="utf-8") as f_read, open("localInfo", "w", encoding="utf-8") as f_write:
for line in f_read:
f_write.write(line)
# 开始选择
def start_choose(flag):
quit_flag = True # 设置一个标志位
num_user_province = 0 # 初始化一个数值
print("Welcome to Springer's post office !")
print("Enter 'quit' to exit the program !")
print("Enter 'return' to return to the previous step !")
while quit_flag: # 开始循环选择地名
if flag == 1: # 选择省级
show_all(1, 0, 0) # 显示字典中所有省级地名
print("If you want to add a new place name, please enter 'add' !")
num_user_province = input("Please select your provice : ")
if num_user_province.isdigit(): # 判断输入是否符合规范
num_user_province = int(num_user_province)
if 0 < num_user_province < count_num(num_user_province, 0, 1) + 1:
print("\nCurrent selection :", num_province(num_user_province))
flag += 1 # 进入下一级选择
else:
print("\nInput contains illegal characters, please re-enter ! ", end="\n")
flag = 1 # 重新选择
elif num_user_province == 'add': # 用户添加地点
user_local_pro = input("\nPlease enter the name of the place you want to add : ")
f_read = open("localInfo", "r", encoding="utf-8")
dic_all = f_read.read()
f_read.close()
dic_all = eval(dic_all)
if user_local_pro in dic_all:
print("\nPlace names already exist. Do not add them again !")
else:
user_add(user_local_pro, "待添加", "待添加", 1)
user_save()
elif num_user_province == 'return': # 返回上一级选择
print("This is the first step !")
flag = 1
elif num_user_province == 'quit': # 用户主动选择退出
print("Looking forward to your next visit !")
quit_flag = False
else:
print("Input contains illegal characters, please re-enter ! ", end="\n\n")
flag = 1
elif flag == 2: # 选择市级
show_all(2, num_user_province, 0) # 显示字典中所有市级地名
num_user_city = input("Please select your city : ")
if num_user_city.isdigit():
num_user_city = int(num_user_city)
if 0 < num_user_city < count_num(num_user_province, num_user_city, 2) + 1: # 判断输入是否符合规范
print("\nCurrent selection :", num_province(num_user_province), num_city(num_user_province, num_user_city))
flag += 1 # 进入下一级选择
else:
print("\nInput contains illegal characters, please re-enter ! ", end="\n")
flag = 2
elif num_user_city == 'add': # 用户添加地点
user_local_cit = input("\nPlease enter the name of the place you want to add : ")
f_read = open("localInfo", "r", encoding="utf-8")
dic_all = f_read.read()
f_read.close()
dic_all = eval(dic_all)
if user_local_cit in dic_all[num_province(num_user_province)]:
print("\nPlace names already exist. Do not add them again !")
else:
user_add(num_province(num_user_province), user_local_cit, "待添加", 2)
user_save()
elif num_user_city == 'return': # 返回上一级选择
flag -= 1
elif num_user_city == 'quit': # 用户主动选择退出
print("Looking forward to your next visit !")
quit_flag = False
else:
print("Input contains illegal characters, please re-enter ! ", end="\n\n")
flag = 2
elif flag == 3: # 选择县级
show_all(3, num_user_province, num_user_city) # 显示字典中所有县级地名
num_user_country = input("Please select your vountry : ")
if num_user_country.isdigit():
num_user_country = int(num_user_country)
if 0 < num_user_country < count_num(num_user_province, num_user_city, 3) + 1: # 判断输入是否符合规范
str_user_address = num_province(num_user_province), \
num_city(num_user_province, num_user_city), \
num_country(num_user_province, num_user_city, num_user_country)
print("\nSuccessful address selection !Current selection :", end="\n")
for i in str_user_address:
print(i, end=" ")
quit_flag = False # 选择完成,退出
else:
print("\nInput contains illegal characters, please re-enter ! ", end="\n")
flag = 3
elif num_user_country == 'add': # 用户添加地点
user_local_cou = input("\nPlease enter the name of the place you want to add : ")
f_read = open("localInfo", "r", encoding="utf-8")
dic_all = f_read.read()
f_read.close()
dic_all = eval(dic_all)
if user_local_cou in dic_all[num_province(num_user_province)][num_city(num_user_province, num_user_city)]:
print("\nPlace names already exist. Do not add them again !")
else:
user_add(num_province(num_user_province), num_city(num_user_province, num_user_city), user_local_cou, 3)
user_save()
elif num_user_country == 'return': # 返回上一级选择
flag -= 1
elif num_user_country == 'quit': # 用户主动选择退出
print("Looking forward to your next visit !")
quit_flag = False
else:
print("Input contains illegal characters, please re-enter ! ", end="\n\n")
flag = 3
# 调用函数,开始选择地名
start_choose(1)
- localInfo 中内容为
{
'山西省':
{
'太原市':
[
'小店区', '迎泽区', '杏花岭区', '万柏林区'],
'大同市':
[
'城区', '矿区', '南郊区', '新荣区'],
'临汾':
[
'尧都区', '曲沃县', '翼城县', '襄汾县']
},
'黑龙江省':
{
'哈尔滨':
[
'道里区', '南岗区', '平房区', '松北区'],
'齐齐哈尔':
[
'龙沙区', '建华区', '铁峰区', '昂昂溪区'],
'大庆':
[
'萨尔图区', '龙凤区', '红岗区', '让胡路区']
},
'四川省':
{
'成都':
[
'锦江区', '青羊区', '金牛区', '武侯区'],
'自贡':
[
'自流井区', '贡井区', '大安区', '沿滩区'],
'德阳':
[
'中江县', '罗江县', '广汉市', '绵竹市']
}
}
本文内容部分取自百度内容,如有雷同部分请见谅。