Appearance
TXT和CSV文件读写
一、TXT 文件和CSV文件
1. TXT 文件(Text File)
- 内容是纯文本(可以包含字母、数字、符号、中文等,但是没有颜色和图像等。)
- 每一行的数据没有固定格式,适合写入文字、日记、程序日志等
2. CSV文件(Comma-Separated Values)
- 内容按 表格形式组织,每一行表示一条记录
- 每行中的各个数据项用逗号(
,)或其他分隔符隔开 - 常用于表格数据存储,如学生成绩表、商品清单等
TIP
CSV 文件其实也是文本文件,只是按规则分隔,每列有明确的位置。可以理解为:遵循某种规范的 TXT文件。
假设我们有一张学生成绩表:
| 姓名 | 年龄 | 成绩 |
|---|---|---|
| 小明 | 12 | 95 |
| 小红 | 13 | 88 |
| 小刚 | 12 | 92 |
保存成 CSV 后,里面的内容 r如下:
姓名,年龄,成绩
小明,12,95
小红,13,88
小刚,12,92每一行代表一条记录(一个学生),这里每个字段之间用 逗号 , 来分隔(不是所有 csv 文件都是使用逗号分割)。
- 如果一个数据出现了分割符,为了避免被解析成2个列,需要用双引号包起来。
"王小明, Jr.",13,89🤣由于双引号被用来包裹数据,所以如果数据里面出现双引号,需要用连续的两个双引号来表示一个引号,以此类推,两个双引号则需要四个。
不同地区的分隔符可能不一样。有的用
,有的用;有的用制表符(\t),所以 Python 读的时候说明分隔符是比较保险的做法。不同系统换行符不一样:Windows 用
\r\n,macOS / Linux 用\n
二、在 Python 中操作 txt 文件
1. open():打开文件
Python 提供了内置函数 open() 来读写文件,它用于 打开一个文件,返回一个 文件对象,之后可以通过这个文件对象 读取或写入文件内容:
python
f = open(file, mode='r', encoding=None)| 参数 | 说明 |
|---|---|
file | 文件路径(可以是相对路径或绝对路径) |
mode | 文件打开模式,决定读写行为 |
encoding | 编码方式,TXT 文件通常用 'utf-8' |
| 模式 | 说明 | 举例 |
|---|---|---|
'r' | 只读(默认),不存在报错 | open('test.txt', 'r') |
'w' | 写入,清空原文件并从头写入(不存在则新建) | open('test.txt', 'w') |
'a' | 追加写入,不覆盖原文件 | open('test.txt', 'a') |
'+' | 扩展功能 | 'r+', 'w+' |
TIP
这3个参数(
file,mode,encoding)是最常用的,但是open()还有其它的参数,而且encoding也不是第3个参数,所以记得使用关键字传参。'+' 可以理解为功能扩展,对于
r,'+'表示扩展写的功能,所以可以对文件进行读写,对于w,'+'表示为扩展读的功能,所以同样可以对文件进行写读。'r+'和'w+'都是可以读写,但是由于'r+'本质是r,所以文件不存在会报错,而w本质是w,所以文件不存在会创建。
2. write():写入文件内容
Python 提供了文件对象的 write() 方法 来向文件写入内容,它用于 向文件写入字符串(其他类型需要先转换成字符串 str()),而且不会自动换行,如果需要换行要在字符串后加 \n(换行符)。
其语法比较简单:
python
write(str)使用范例:
python
# 打开文件
f = open(r"demo.txt", "w", encoding='utf-8')
# 写入内容
f.write("Hello, Python!\n") # \n 表示换行
f.write("文件操作真好玩!")
# 关闭文件
f.close()程序中,第2行,r"demo.txt"的r表示一个原始字符串,即反斜杠'\'不会被当成转义字符,否则可能会出错。
⚠:打开一个文件进行操作后,一定要记得关闭文件,这是在告诉操作系统:其他程序可以开始操作这个文件了。
3. read():读取文件内容
Python 提供了3个常用的读文件内容的函数,以适用不同的情况:
| 函数 | 读多少 | 返回值类型 | 指针变化 | 典型用途 |
|---|---|---|---|---|
read(size) | 读 size 个字符(缺省表示全部读取) | str | 向后移动 size 个字符 | 读取固定长度 / 整个文件 |
readline() | 读 一整行(含 \n) | str | 移到下一行开头 | 按行处理文本 |
readlines() | 读 剩余所有行 | list[str] | 移到文件末尾 | 小文件一次性处理 |
现在有一个demo.txt文件,内容如下:
md
Hello
Python
File分别使用不同的读函数进行读取:
使用 read()读取全部:
python
f = open("demo.txt", "r", encoding="utf-8")
content = f.read()
print(content)
f.close()打印的内容为:
md
Hello
Python
File使用 readline()按顺序读取2行:
python
f = open("demo.txt", "r", encoding="utf-8")
line1 = f.readline()
line2 = f.readline()
print(line1)
print(line2)
f.close()打印的内容为:
md
Hello
Python使用 readlines()读取所有的行,每一行作为列表的一个元素:
python
f = open("demo.txt", "r", encoding="utf-8")
lines = f.readlines()
print(lines)
f.close()打印的内容为:
md
['Hello\n', 'Python\n', 'File']4. 使用 with open打开文件
相比直接的使用open()函数打开文件,Python 更加推荐使用 with open打开文件:
python
with open(r"demo.txt", "w", encoding='utf-8') as f:
f.write("Hello, Python!\n")
f.write("文件操作真好玩!")with open 打开文件后进行操作后,会自动的调用 close()函数进行关闭。并且,在文件打开的后续操作中,如果程序出现异常,文件也能正常的关闭。
三、在 Python 中操作 csv 文件
正如前文所述,csv 是遵循某种规范的 txt文件,所以我们可以使用操作 txt 的函数进行操作,根据其特点进行数据的提取。不过,Python 标准库提供了 csv 模块:
python
import csv # 导入 csv 模块在操作txt文本文件时候,我们使用了内嵌函数open()打开一个文件,并获取一个文件对象,通过这个文件对象来对文件进行读写操作,文件对象自带了读和写(read()和write())方法,但是如果要使用csv模块,我们需要根据这个open()返回的文件对象,再创建一个读csv的读/写对象,然后使用这个csv创建出来的读/写对象进行相应的操作:
python
import csv
# 打开 CSV 文件准备读取
with open("data.csv", mode="r", encoding="utf-8") as f:
reader = csv.reader(f) # 返回一个 reader 对象
# 读取内容
# 打开 CSV 文件准备写入
with open("data.csv", mode="w", encoding="utf-8", newline="") as f:
writer = csv.writer(f) # 返回一个 writer 对象
# 写入内容1. csv.reader() :创建csv读对象(列表)
csv.reader()方法需要传入一个文件对象,接着返回一个可迭代对象,每次迭代产生的是一个列表。
python
import csv
with open("csv_demo.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row) # 每行是一个列表注意到,这里的 reader是一个可迭代的对象,它的核心是维护一个指向csv_demo.csv的指针,使用for循环时,不断的读取并移动这个指针,所以在这段程序中,若后续继续使用 for 循环遍历将什么也读取不到,因为reader对象维护的指针已经指向文件最后了。这里每次循环得到的是一个列表。
若需要直接处理数据,不需要表头,此时可以使用 **next(reader)**来跳过表头:
python
import csv
with open("csv_demo.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f) # 跳过表头
next(reader)
for row in reader:
print(row) # 每行是一个列表我们还可以把reader迭代器迭代的元素都存储到列表中,这样可以使用列表的方法来对齐进行操作,当然如果文件很大,列表也会相应的占用很多内存:
python
import csv
with open("csv_demo.csv", "r", encoding="utf-8") as f:
reader = list(csv.reader(f))
for row in reader:
print(row) # 每行是一个列表这里的reader已经是一个列表了,所以它可以被重复遍历等,另外,也可以通过列表切换进行表头的跳过:
python
import csv
with open("csv_demo.csv", "r", encoding="utf-8") as f:
reader = list(csv.reader(f))
for row in reader[1:]: #reader[0]被它跳过,这里存放的是表头的信息
print(row) # 每行是一个列表2. csv.DictReader :创建csv读对象(字典)
csv.DictReader方法同样需要传入一个文件对象,接着返回一个可迭代对象,每次迭代产生的是一个字典,其表头作为键,对于的数据作为值:
python
import csv
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(row)由于表头作为字典的键,对应的数据作为值,所以这种读取方式没有“跳过表头”的操作。
3. csv.writer():创建 CSV 写对象(列表方式)
csv.writer() 方法需要传入一个文件对象,返回一个 writer 对象,然后使用它的 writerow() 或 writerows() 方法写入内容,每一行是一个列表。
python
import csv
# 打开 CSV 文件准备写入
with open("csv_demo.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f) # 返回 writer 对象
# 写入表头
writer.writerow(['姓名', '年龄', '成绩'])
# 写入一行数据
writer.writerow(['小明', 12, 95])
# 写入多行数据
rows = [
['小红', 13, 88],
['小刚', 12, 92]
]
writer.writerows(rows)⚠ :newline=""是必须的,否则写出的 CSV 每行可能有空行。
4. csv.DictWriter():创建 CSV 写对象(字典方式)
csv.DictWriter() 方法需要传入文件对象和 fieldnames 列名列表,返回一个 writer 对象,然后使用 writeheader() 写表头,writerow() 或 writerows() 写入数据,每一行是一个字典。
python
import csv
with open("data.csv", "w", encoding="utf-8", newline="") as f:
# 告诉机器列名和顺序
fieldnames = ['姓名', '年龄', '成绩']
writer = csv.DictWriter(f, fieldnames=fieldnames)
# 写表头
writer.writeheader()
# 写一条记录
writer.writerow({'姓名':'小明', '年龄':12, '成绩':95})
# 写多条记录
writer.writerows([
{'姓名':'小红', '年龄':13, '成绩':88},
{'姓名':'小刚', '年龄':12, '成绩':92}
])四、文件与字符串处理函数
1. split():分割字符串
split()把一个字符串按照指定分隔符分成多个部分,返回列表。
python
line = "小明,12,95"
data = line.split(",")
print(data) # ['小明', '12', '95']
print("小红~15~九年级".split("~")) # ['小红', '15', '九年级']2. strip():去掉首尾空白或指定字符
str.strip参数为要去掉的字符(只处理首尾),默认空白字符(空格、换行\n、制表符\t)
python
line = "小明,12,95\n"
clean_line = line.strip()
print(clean_line) # 小明,12,953. join():合并字符串
join()把序列(列表、元组)里的字符串用指定分隔符拼接成一个字符串
python
data = ['小明', '12', '95']
line = ",".join(data)
print(line) # 小明,12,95