Skip to content

文件操作 ​

日常我们在操作电脑上的文件,对文件进行读写时,基本分为三步操作:打开、读/写、关闭 。 那我们在程序中操作文件,也是类似的道理,也需要分为这么三步操作:打开、读/写、关闭。

读文件 ​

python
# -----------------读文件---------------------
# 1 打开文件
f = open("resource/望庐山瀑布.txt", "r", encoding="utf-8")
# 2 读文件
s = f.read()  # 读所有数据,结果是字符串
print(s, type(s))

# line = f.readline()  # 读一行数据,结果是字符串
# print(line, type(line))

# line_list = f.readlines()  # 读所有数据,结果是列表
# print(line_list, type(line_list))

# 3 关闭文件(释放资源)
f.close()

提示

  • "r":表示的是操作模式,r 代表 read ,表示读文件
  • encoding:表示的是文件的编码
  • 编码:是将字符(文字、数字、符号)转换为计算机能够存储和处理的数字代码的规则系统,如:ASCII、GBK、UTF-8 。
    • ASCII:是最简单的西文编码方案,主要是针对于 数字、字母、常见符号 进行编码,无法对中文、韩文、日文等语言进行编码
    • GBK:中国制定的一个汉字字符集编码标准,兼容ASCII,但是无法对 韩文、日文 进行编码
    • UTF-8:目前互联网上最通用的字符编码标准,兼容 ASCII、全球通用,已经成为现代软件、网络和存储中最正确、最推荐的字符编码。

写文件 ​

# # 写文件
# 1. 打开文件
f = open("resources/静夜思.txt", "w", encoding="utf-8")

# 2. 写入文件内容
f.write("静夜思(李白)\n\n")
f.write("窗前明月光,\n")
f.write("疑是地上霜。\n")
f.write("举头望明月,\n")
f.write("低头思故乡。\n")

# 3. 关闭文件
f.close()
# 如何查看操作的文件是否已经关闭了
print(f.closed) #返回bool值,True或者False

注意!!!

如果操作完文件,未调用close方法关闭文件,同时程序没有停止运行,那么这个文件将一直被Python程序占用,无法操作 。

释放资源 ​

python
# # 写文件
# 1. 打开文件
f = open("resources/静夜思.txt", "w", encoding="utf-8")

# 2. 写入文件内容
f.write("静夜思(李白)\n\n")
f.write("窗前明月光,\n")
f.write("疑是地上霜。\n")
# 下面的代码执行出错,就意味着后续的代码不再继续执行,那么文件将始终被占用
print(1 / 2)
f.write("举头望明月,\n")
f.write("低头思故乡。\n")

# 3. 关闭文件
f.close()

**思考:**如果操作文件过程中,代码运行出现了异常,那后面的代码是无法继续执行的,也就意味着,关闭文件的代码也是无法运行的,这个文件并没有正确的关闭掉,那么此时这个文件将一直被该Python程序占用,无法操作。那怎么解决这个问题呢 ?

那其实呢,有两种方案都可以解决这个问题。

方案一:try ... finally ...【繁琐】

python
# 写文件
# 1. 打开文件
f = open("resources/静夜思.txt", "w", encoding="utf-8")

try:
    # 2. 写入文件内容
    f.write("静夜思(李白)\n\n")
    f.write("窗前明月光,\n")
    i = 1 / 0
    f.write("疑是地上霜。\n")
    f.write("举头望明月,\n")
    f.write("低头思故乡。\n")
finally:
    # 3. 关闭文件
    print("关闭文件")
    f.close()

try...finally 是一种异常处理结构,其中的 finally 子句用于定义 无论是否发生异常,都会被执行 的清理/资源释放代码。【finally 代码块必须跟在try之后,不能单独出现】

方案二:with 上下文管理器 【推荐】

with 上下文管理器,是 Python 中用于资源管理的语法糖,它能够自动处理资源的获取和释放,确保即使在发生异常的情况下,资源也能被正确清理。

python
with 表达式 [as 变量]:
    代码块

# 可以同时管理多个资源
with 表达式1 as 变量1, 表达式2 as 变量2:
    代码块

# 写文件
# 1. 打开文件
with open("demo.txt", "w", encoding="utf-8") as f:
    # 2. 写入文件内容
    f.write("静夜思(李白)\n\n")
    f.write("窗前明月光,\n")
    f.write("疑是地上霜。\n")
    # 及时这里代码执行出现了错误,也不影响后续被占用文件的释放
    print(1 / 2)
    f.write("举头望明月,\n")
    f.write("低头思故乡。\n")
# 注意:f在表达式的外面也是可以反问到的
print(f.closed) # True

路径写法 ​

关于文件路径写法,主要分为两类:

  • 相对路径: 从当前文件所在目录开始查找 【推荐】
    • . : 当前目录 ----> ./resources/望庐山瀑布.txt ./ 可以省略
    • ..: 上一级目录 ----> ../第2章/file/寻隐者不遇.txt ----> ../../第2章/file/寻隐者不遇.txt
python
# 读取文件
with open("resources/望庐山瀑布.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)


# 写文件
# a: append, 追加内容; w: write, 覆盖内容; ----> 文件不存在, 则创建文件;
with open("resources/静夜思.txt", "a", encoding="utf-8") as f:
    f.write("静夜思(李白)\n\n")
    f.write("窗前明月光,\n")
    f.write("疑是地上霜。\n")
    f.write("举头望明月,\n")
    f.write("低头思故乡。\n")
  • **绝对路径:**从文件系统根目录开始查找, 文件位置的完整路径 (注意: 反斜杠 在字符串中表示的是转义字符, \n \t)
    • 方式一: D:\\Python-Project\\py_project01\\第3章\\resources\\望庐山瀑布.txt
    • 方式二: D:/Python-Project/py_project01/第3章/resources/望庐山瀑布.txt
python
# 读取文件
with open("D:\\Python-Project\\py_project01\\第3章\\resources\\望庐山瀑布.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)


# 写文件
# a: append, 追加内容; w: write, 覆盖内容; ----> 文件不存在, 则创建文件;
with open("D:/Python-Project/py_project01/第3章/resources/望庐山瀑布.txt", "a", encoding="utf-8") as f:
    f.write("静夜思(李白)\n\n")
    f.write("窗前明月光,\n")
    f.write("疑是地上霜。\n")
    f.write("举头望明月,\n")
    f.write("低头思故乡。\n")

提示

在项目开发中,推荐使用相对路径写法,可移植性更好、路径简洁、易于阅读 。

操作模式 ​

关于文件的操作模式,常见的分为三种,分别是:

  • r:只读的方式打开文件,指针放在文件的开头。(默认模式)
  • w:只写入模式,从头编辑,原有内容会被删除;文件不存在则创建新文件
  • a:追加模式,新内容会被追加在原有内容之后;文件不存在则创建新文件
python
# 读取文件
# r: 只读的方式打开文件,指针放在文件的开头
with open("resources/望庐山瀑布.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)


# 写文件
# w: write, 写入模式, 从文件开头开始写入, 原有内容将会被删除; ----> 文件不存在, 则创建文件;
with open("resources/静夜思.txt", "w", encoding="utf-8") as f:
    f.write("静夜思(李白)\n\n")
    f.write("窗前明月光,\n")
    f.write("疑是地上霜。\n")
    f.write("举头望明月,\n")
    f.write("低头思故乡。\n")
    
# 写文件
# a: append, 追加模式, 新内容会被追加在原有内容之后; ----> 文件不存在, 则创建文件;
with open("resources/静夜思.txt", "a", encoding="utf-8") as f:
    f.write("静夜思(李白)\n\n")
    f.write("窗前明月光,\n")
    f.write("疑是地上霜。\n")
    f.write("举头望明月,\n")
    f.write("低头思故乡。\n")

json操作 ​

JSON是软件开发中最常用的数据交换格式,而为了简化JSON数据的处理,在Python标准库中就提供了处理JSON数据的核心模块 json。我们可以基于json模块中提供的两个函数,来完成json数据的序列化(将字典dict对象转为json格式字符串,存入文件) 和 反序列化(将文件中的json格式字符串,转为字典dict对象)。

序列化操作 ​

json.dump()和js中的JSON.stringify一样的功能。

python
# json序列化:将列表/字典中的数据 以json的格式 写到文件中
# 1 准备数据
import json

user_list = [
    {"name": "张益达", "age": 18, "gender": "男"},
    {"name": "张伟", "age": 19, "gender": "女"},
    {"name": "张大炮", "age": 22, "gender": "男"}
]
# 2 使用json模块的dump方法写到文件中
with open("user.json", "w", encoding="utf-8") as f:
    # 参数1:要写的数据。参数2:要写入的文件。 参数3(ensure_ascii=False):是否采用ascii编码,默认值是True会对中文编码
    # 参数4(indent="\t"):使用\t缩进,格式好看一些。如果值为数字,则表示缩进n个空格。
    json.dump(user_list, f, ensure_ascii=False, indent=2)
  • ensure_ascii: 默认为True, 确保所有的数据输出的数据都是ascii编码(非ASCII码会进行转义); False, 非ASCII码保留原样输出
  • indent: 会在输出的json数据中添加缩进(格式化)

反序列化操作 ​

json.load()和js中的JSON.parse()功能一样的功能。

python
import json

# json反序列化:将文件中的json数据读出来,转换乘列表/字典。
# 1 打开文件
with open("user.json", "r", encoding="utf-8") as f:
    # 2 使用json模块的load方法加载json数据反序列化
    my_list = json.load(f)
    print(my_list,type(my_list))